PS1 script to AHK

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
rp0000009
Posts: 9
Joined: 17 Jun 2014, 13:22

PS1 script to AHK

Post by rp0000009 » 24 Sep 2020, 16:06

I've found a following Powershell script and need help to convert to Autohotkey and instead of echoing output, assign to a variable to add to an excel file. If multiple monitors then mon1, mon2, etc. Greatly appreciate your assistance.

Code: Select all

function Decode {
    If ($args[0] -is [System.Array]) {
        [System.Text.Encoding]::ASCII.GetString($args[0])
    }
    Else {
        "Not Found"
    }
}

echo "Name, Serial"

ForEach ($Monitor in Get-WmiObject WmiMonitorID -Namespace root\wmi) {  
    $Name = Decode $Monitor.UserFriendlyName -notmatch 0
    $Serial = Decode $Monitor.SerialNumberID -notmatch 0
	
    echo "$Name, $Serial"
}
[Mod edit: Codebox added.]
User avatar
FanaticGuru
Posts: 1906
Joined: 30 Sep 2013, 22:25

Re: PS1 script to AHK

Post by FanaticGuru » 24 Sep 2020, 20:14

rp0000009 wrote:
24 Sep 2020, 16:06
I've found a following Powershell script and need help to convert to Autohotkey and instead of echoing output, assign to a variable to add to an excel file. If multiple monitors then mon1, mon2, etc. Greatly appreciate your assistance.

Code: Select all

function Decode {
    If ($args[0] -is [System.Array]) {
        [System.Text.Encoding]::ASCII.GetString($args[0])
    }
    Else {
        "Not Found"
    }
}

echo "Name, Serial"

ForEach ($Monitor in Get-WmiObject WmiMonitorID -Namespace root\wmi) {  
    $Name = Decode $Monitor.UserFriendlyName -notmatch 0
    $Serial = Decode $Monitor.SerialNumberID -notmatch 0
	
    echo "$Name, $Serial"
}
[Mod edit: Codebox added.]

Here is basically the same thing in AHK.

Code: Select all

wmi := ComObjGet("winmgmts:{impersonationLevel=impersonate}!\\" A_ComputerName "\root\wmi")
Monitor_Info := {}
for Monitor in wmi.ExecQuery("Select * from WmiMonitorID")
{	
	Name := Decode(Monitor.UserFriendlyName)
	Serial := Decode(Monitor.SerialNumberID)
	Monitor_Info.Push({Name: Name, Serial: Serial})
}

for index, Monitor in Monitor_Info ; display information
	MsgBox % "Monitor #" index "`n" Monitor.Name "`n" Monitor.Serial 

Decode(Arr)
{
	for Char in Arr
		Decoded .= Chr(Char)
	return Decoded
}
FG
Hotkey Help - Help Dialog for Currently Running AHK Scripts
AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon
Hotstring Manager - Create and Manage Hotstrings
[Class] WinHook - Create Window Shell Hooks and Window Event Hooks
rp0000009
Posts: 9
Joined: 17 Jun 2014, 13:22

Re: PS1 script to AHK

Post by rp0000009 » 25 Sep 2020, 08:07

Thanks FantasticGuru, really appreciate you. I ran your script and got no message box. I found something similar listed below but not getting similar response like PS1.

Script found in forum:

Code: Select all

objWMIService := ComObjGet("winmgmts:{impersonationLevel=impersonate}!\\" A_ComputerName "\root\cimv2")
For objDeskMon in objWMIService.ExecQuery("Select * from Win32_DesktopMonitor")
	DeviceID := objDeskMon.DeviceID, PNPDeviceID := objDeskMon.PNPDeviceID, MonitorType := objDeskMon.MonitorType, MonitorManufacturer := objDeskMon.MonitorManufacturer
Msgbox %  DeviceID "`n"  PNPDeviceID "`n" MonitorType  "`n" MonitorManufacturer
[Mod edit: [code][/code] tags added.]

Output from AHK vs. PS1 scripts:
[img]C:\temp\AHK_Output.JPG[/img] vs. [img]C:\temp\PS1_Output.JPG[/img]
gregster
Posts: 9001
Joined: 30 Sep 2013, 06:48

Re: PS1 script to AHK

Post by gregster » 25 Sep 2020, 09:52

rp0000009 wrote:
25 Sep 2020, 08:07
Output from AHK vs. PS1 scripts:
[img]C:\temp\AHK_Output.JPG[/img] vs. [img]C:\temp\PS1_Output.JPG[/img]
If you want to upload your locally stored pictures to the forums, this is not gonna work.
Please use the Attachments tab in the forum's 'Full Editor'. Scroll a bit down from the edit field, then click Attachments > Add files > (Place inline)

add files.png
add files.png (4.41 KiB) Viewed 1725 times

The look might be a bit different, depending on your forum theme...
rp0000009
Posts: 9
Joined: 17 Jun 2014, 13:22

Re: PS1 script to AHK

Post by rp0000009 » 25 Sep 2020, 10:45

AHK_Output.JPG
AHK_Output.JPG (5.64 KiB) Viewed 1705 times
PS1_Output.JPG
PS1_Output.JPG (5.4 KiB) Viewed 1705 times
User avatar
FanaticGuru
Posts: 1906
Joined: 30 Sep 2013, 22:25

Re: PS1 script to AHK

Post by FanaticGuru » 25 Sep 2020, 12:11

rp0000009 wrote:
25 Sep 2020, 08:07
Thanks FantasticGuru, really appreciate you. I ran your script and got no message box. I found something similar listed below but not getting similar response like PS1.

Script found in forum:

Code: Select all

objWMIService := ComObjGet("winmgmts:{impersonationLevel=impersonate}!\\" A_ComputerName "\root\cimv2")
For objDeskMon in objWMIService.ExecQuery("Select * from Win32_DesktopMonitor")
	DeviceID := objDeskMon.DeviceID, PNPDeviceID := objDeskMon.PNPDeviceID, MonitorType := objDeskMon.MonitorType, MonitorManufacturer := objDeskMon.MonitorManufacturer
Msgbox %  DeviceID "`n"  PNPDeviceID "`n" MonitorType  "`n" MonitorManufacturer
[Mod edit: [code][/code] tags added.]

Output from AHK vs. PS1 scripts:
[img]C:\temp\AHK_Output.JPG[/img] vs. [img]C:\temp\PS1_Output.JPG[/img]

That code is similar but looks at Win32_DestopMonitor which is a little different than WmiMonitorID. Win32_DestopMonitor can provide some information on the monitor but does not contain the "UserFriendlyName".

No MsgBox means the code is not finding anything with wmi.ExecQuery("Select * from WmiMonitorID"). Why that might be I do not know. The code works for me.

Maybe something non-typically about your setup. Old version of Autohotkey, old version of Windows, non-English setup, really just guessing here.

FG
Hotkey Help - Help Dialog for Currently Running AHK Scripts
AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon
Hotstring Manager - Create and Manage Hotstrings
[Class] WinHook - Create Window Shell Hooks and Window Event Hooks
tmplinshi
Posts: 1604
Joined: 01 Oct 2013, 14:57

Re: PS1 script to AHK

Post by tmplinshi » 26 Sep 2020, 01:47

How about getting output from powershell..

Code: Select all

#include CLR.ahk ; https://www.autohotkey.com/boards/viewtopic.php?t=4633

script =
(
   function Decode {
       If ($args[0] -is [System.Array]) {
           [System.Text.Encoding]::ASCII.GetString($args[0])
       }
       Else {
           "Not Found"
       }
   }

   echo "Name, Serial"

   ForEach ($Monitor in Get-WmiObject WmiMonitorID -Namespace root\wmi) {  
       $Name = Decode $Monitor.UserFriendlyName -notmatch 0
       $Serial = Decode $Monitor.SerialNumberID -notmatch 0
      
       echo "$Name, $Serial"
   }
)

MsgBox % data := RunPowershellCode(script)
FileAppend, % data, % A_Desktop "\Monitor.csv"
ExitApp

RunPowershellCode(ByRef psCode) {
	static ps
	if !ps {
		cSharp =
		(
			using System.Text;
			using System.Collections.ObjectModel;
			using System.Management.Automation;
			using System.Management.Automation.Runspaces;

			public class ps
			{
				public string RunScript(string scriptText)
				{
					Runspace runspace = RunspaceFactory.CreateRunspace();
					runspace.Open();

					Pipeline pipeline = runspace.CreatePipeline();
					pipeline.Commands.AddScript(scriptText);
					pipeline.Commands.Add("Out-String");

					Collection<PSObject> results = pipeline.Invoke();

					runspace.Close();
					return results[0].ToString();
				}
			}
		)

		asm := CLR_CompileC#( cSharp, "System.Core.dll | C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Management.Automation\v4.0_3.0.0.0__31bf3856ad364e35\System.Management.Automation.dll" )
		ps := asm.CreateInstance("ps")
	}
	return ps.RunScript(psCode)
}
rp0000009
Posts: 9
Joined: 17 Jun 2014, 13:22

Re: PS1 script to AHK

Post by rp0000009 » 26 Sep 2020, 09:24

where to download CLR.ahk from? Link https://www.autohotkey.com/boards/viewtopic.php?t=4633 is not working as I'm getting "Information: Code contents not found".
tmplinshi
Posts: 1604
Joined: 01 Oct 2013, 14:57

Re: PS1 script to AHK

Post by tmplinshi » 26 Sep 2020, 09:35

You can copy CLR.ahk from the codebox, at the end of the post
rp0000009
Posts: 9
Joined: 17 Jun 2014, 13:22

Re: PS1 script to AHK

Post by rp0000009 » 28 Sep 2020, 08:14

I appreciate all your help. I've saved code as CLR.ahk in the autohotkey\lib folder and updated the #include to the path. When I run it, I'm getting msgbox with name, serial. Also CSV file has same. How do i get monitor info to populate?
CSVoutput.JPG
CSVoutput.JPG (2.96 KiB) Viewed 1565 times
AHKoutput.JPG
AHKoutput.JPG (4.88 KiB) Viewed 1565 times
tmplinshi
Posts: 1604
Joined: 01 Oct 2013, 14:57

Re: PS1 script to AHK

Post by tmplinshi » 28 Sep 2020, 11:50

try:

Code: Select all

SetBatchLines -1

script =
(
   echo "Name, Serial"

   ForEach ($Monitor in Get-WmiObject WmiMonitorID -Namespace root\wmi) {  
       $Name = $Monitor.UserFriendlyName -notmatch 0
       $Serial = $Monitor.SerialNumberID -notmatch 0
       echo "$Name, $Serial"
   }
)

MsgBox % data := decode( RunPowershellCode(script) )
FileOpen(A_Desktop "\Monitor.csv", "w").Write(data)
ExitApp

decode(data) {
	data := StrReplace(data, ",", " , ")
	Loop, Parse, data, `n, `r
	{
		Loop, Parse, A_LoopField, %A_Space%
			decoded .= (A_LoopField ~= "\d") ? Chr(A_LoopField) : A_LoopField
		decoded .= "`r`n"
	}
	return decoded
}

RunPowershellCode(ByRef psCode) {
	static ps
	if !ps {
		cSharp =
		(
			using System.Text;
			using System.Collections.ObjectModel;
			using System.Management.Automation;
			using System.Management.Automation.Runspaces;

			public class ps
			{
				public string RunScript(string scriptText)
				{
					Runspace runspace = RunspaceFactory.CreateRunspace();
					runspace.Open();

					Pipeline pipeline = runspace.CreatePipeline();
					pipeline.Commands.AddScript(scriptText);
					pipeline.Commands.Add("Out-String");

					Collection<PSObject> results = pipeline.Invoke();

					runspace.Close();
					return results[0].ToString();
				}
			}
		)

		asm := CLR_CompileC#( cSharp, "System.Core.dll | C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Management.Automation\v4.0_3.0.0.0__31bf3856ad364e35\System.Management.Automation.dll" )
		ps := asm.CreateInstance("ps")
	}
	return ps.RunScript(psCode)
}
rp0000009
Posts: 9
Joined: 17 Jun 2014, 13:22

Re: PS1 script to AHK

Post by rp0000009 » 30 Sep 2020, 07:36

Tmplinshi I've tried your script and still getting same results as posted above with or without including CLR.ahk file. Not seeing information my friend. I do appreciate your efforts. :(
malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

Re: PS1 script to AHK

Post by malcev » 01 Oct 2020, 06:38

Monitor names You can get with EnumDisplayDevices help.
For example:

Code: Select all

VarSetCapacity(display_device, 840, 0)
NumPut(840, display_device, 0, "uint")
DllCall("EnumDisplayDevices", "str", "\\.\DISPLAY1", "uint", 0, "ptr", &display_device, "uint", 0)
MsgBox, % StrGet(&display_device + 68)
Other info You can get with EDID.
https://en.wikipedia.org/wiki/Extended_Display_Identification_Data
https://glenwing.github.io/docs/VESA-EEDID-A2.pdf
User avatar
FanaticGuru
Posts: 1906
Joined: 30 Sep 2013, 22:25

Re: PS1 script to AHK

Post by FanaticGuru » 01 Oct 2020, 12:18

malcev wrote:
01 Oct 2020, 06:38
Monitor names You can get with EnumDisplayDevices help.
For example:

Code: Select all

VarSetCapacity(display_device, 840, 0)
NumPut(840, display_device, 0, "uint")
DllCall("EnumDisplayDevices", "str", "\\.\DISPLAY1", "uint", 0, "ptr", &display_device, "uint", 0)
MsgBox, % StrGet(&display_device + 68)
Other info You can get with EDID.
https://en.wikipedia.org/wiki/Extended_Display_Identification_Data
https://glenwing.github.io/docs/VESA-EEDID-A2.pdf

That gets you the same name as Win32_DesktopMonitor which is often not that descriptive. For me for example that returns "Generic PnP Monitor" where as UserFriendlyName through WmiMonitorID returns "LG Ultra HD".

FG
Hotkey Help - Help Dialog for Currently Running AHK Scripts
AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon
Hotstring Manager - Create and Manage Hotstrings
[Class] WinHook - Create Window Shell Hooks and Window Event Hooks
malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

Re: PS1 script to AHK

Post by malcev » 01 Oct 2020, 18:34

Then You can try like this:

Code: Select all

DllCall("GetDisplayConfigBufferSizes", "uint", QDC_ONLY_ACTIVE_PATHS := 2, "uint*", numPathArrayElements, "uint*", numModeInfoArrayElements)
VarSetCapacity(DISPLAYCONFIG_PATH_INFO, (20+48+4)*numPathArrayElements, 0)
VarSetCapacity(DISPLAYCONFIG_MODE_INFO, 64*numModeInfoArrayElements, 0)
DllCall("QueryDisplayConfig", "uint", QDC_ONLY_ACTIVE_PATHS := 2, "ptr", &numPathArrayElements, "ptr", &DISPLAYCONFIG_PATH_INFO, "ptr", &numModeInfoArrayElements, "ptr", &DISPLAYCONFIG_MODE_INFO, "uint", 0)
loop % NumGet(numPathArrayElements, "int")
{
   adapterId := NumGet(DISPLAYCONFIG_PATH_INFO, (A_Index-1)*72+20, "int64")
   id := NumGet(DISPLAYCONFIG_PATH_INFO, (A_Index-1)*72+28, "uint")
   VarSetCapacity(DISPLAYCONFIG_TARGET_DEVICE_NAME, 420, 0)
   NumPut(DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME := 2, DISPLAYCONFIG_TARGET_DEVICE_NAME, 0, "uint")
   NumPut(420, DISPLAYCONFIG_TARGET_DEVICE_NAME, 4, "uint")
   NumPut(adapterId, DISPLAYCONFIG_TARGET_DEVICE_NAME, 8, "int64")
   NumPut(id, DISPLAYCONFIG_TARGET_DEVICE_NAME, 16, "uint")
   DllCall("DisplayConfigGetDeviceInfo", "ptr", &DISPLAYCONFIG_TARGET_DEVICE_NAME)
   MsgBox, % StrGet(&DISPLAYCONFIG_TARGET_DEVICE_NAME + 36)
}
User avatar
FanaticGuru
Posts: 1906
Joined: 30 Sep 2013, 22:25

Re: PS1 script to AHK

Post by FanaticGuru » 02 Oct 2020, 10:50

malcev wrote:
01 Oct 2020, 18:34
Then You can try like this:

Code: Select all

DllCall("GetDisplayConfigBufferSizes", "uint", QDC_ONLY_ACTIVE_PATHS := 2, "uint*", numPathArrayElements, "uint*", numModeInfoArrayElements)
VarSetCapacity(DISPLAYCONFIG_PATH_INFO, (20+48+4)*numPathArrayElements, 0)
VarSetCapacity(DISPLAYCONFIG_MODE_INFO, 64*numModeInfoArrayElements, 0)
DllCall("QueryDisplayConfig", "uint", QDC_ONLY_ACTIVE_PATHS := 2, "ptr", &numPathArrayElements, "ptr", &DISPLAYCONFIG_PATH_INFO, "ptr", &numModeInfoArrayElements, "ptr", &DISPLAYCONFIG_MODE_INFO, "uint", 0)
loop % NumGet(numPathArrayElements, "int")
{
   adapterId := NumGet(DISPLAYCONFIG_PATH_INFO, (A_Index-1)*72+20, "int64")
   id := NumGet(DISPLAYCONFIG_PATH_INFO, (A_Index-1)*72+28, "uint")
   VarSetCapacity(DISPLAYCONFIG_TARGET_DEVICE_NAME, 420, 0)
   NumPut(DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME := 2, DISPLAYCONFIG_TARGET_DEVICE_NAME, 0, "uint")
   NumPut(420, DISPLAYCONFIG_TARGET_DEVICE_NAME, 4, "uint")
   NumPut(adapterId, DISPLAYCONFIG_TARGET_DEVICE_NAME, 8, "int64")
   NumPut(id, DISPLAYCONFIG_TARGET_DEVICE_NAME, 16, "uint")
   DllCall("DisplayConfigGetDeviceInfo", "ptr", &DISPLAYCONFIG_TARGET_DEVICE_NAME)
   MsgBox, % StrGet(&DISPLAYCONFIG_TARGET_DEVICE_NAME + 36)
}

That works for me and returns the UserFriendlyName. That is an impressive amount of address calculations.

There are a surprising amount of ways to get information on the monitor.

FG
Hotkey Help - Help Dialog for Currently Running AHK Scripts
AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon
Hotstring Manager - Create and Manage Hotstrings
[Class] WinHook - Create Window Shell Hooks and Window Event Hooks
rp0000009
Posts: 9
Joined: 17 Jun 2014, 13:22

Re: PS1 script to AHK

Post by rp0000009 » 08 Oct 2020, 11:11

Thanks everyone. I've tried all these suggestion but msgbox is still blank.
Post Reply

Return to “Ask for Help (v1)”