有响应但没有 window 的 Powershell 脚本?
Powershell script with response and no window?
我想 运行 PowerShell 中的命令并使用 AutoHotkey 中的响应。我找到了很多关于如何 运行 PowerShell 脚本的信息,但是 none 说明了如何在 AutoHotkey 中使用它的响应。
我试过这个:
MsgBox % ComObjCreate("WScript.Shell").Exec("powershell.exe -ExecutionPolicy Bypass -WindowStyle Hidden -noProfile -nologo dir").StdOut.ReadAll()
但这仍然会在很短的时间内闪烁 window。我每 25 毫秒循环一次此命令,因此让 window 闪烁通常不是有效的解决方案。
编辑:
最后得出这个最简单的解决方案:
cmd = powershell.exe -command "(Get-Process -Id " %pid% ").Threads[1].WaitReason"
shell := setup()
Loop {
string := shell.exec(cmd).stdout.readall()
...}
setup() {
detecthiddenwindows on
run %comspec% /k ,, hide useerrorlevel, pid
winwait ahk_pid %pid%,, 10
DllCall("AttachConsole", "uint", pid)
con := DllCall("CreateFile"
, "str", "CONOUT$", "uint", 0xC0000000, "uint", 7, "uint", 0, "uint", 3, "uint", 0, "uint", 0)
oshell := comobjcreate("wscript.shell")
return oshell
}
注意:将 AHK (AutoHotkey) 与外部 PowerShell 进程一起使用不适合必须 运行 每 25 毫秒 的任务,正如您自己发现的那样- 处理开销太大。
如果只需要获取目录列表,您可以使用内置的 AHK 功能,使用 Loop
command for files - see this answer.
下面的解决方案一般演示了如何运行控制台程序:
- 隐藏(不闪烁windows)
- 同步(等待退出)
- 其 输出被捕获
来自 AHK。
您不能将 ComObjCreate("WScript.Shell").Exec()
用于 运行 控制台应用程序 隐藏。
相反,虽然您可以使用 RunWait
隐藏 运行,但不能使用它来 捕获(控制台)输出。
解决方法 是:
使用RunWait
.
将输出重定向添加到(临时)文件到您的控制台程序调用。
之后用 FileRead
读取该文件的内容(并删除临时文件)。
; Get a temporary file path
tempFile := A_Temp "\" DllCall("GetCurrentProcessId") ".txt" ; "
; Run the console program hidden, redirecting its output to
; the temp. file (with a program other than powershell.exe or cmd.exe,
; prepend %ComSpec% /c; use 2> to redirect error output), and wait for it to exit.
RunWait, powershell.exe -ExecutionPolicy Bypass -WindowStyle Hidden -noProfile dir > %tempFile%,, Hide
; Read the temp file into a variable and then delete it.
FileRead, content, %tempFile%
FileDelete, %tempFile%
; Display the result.
MsgBox % content
我想 运行 PowerShell 中的命令并使用 AutoHotkey 中的响应。我找到了很多关于如何 运行 PowerShell 脚本的信息,但是 none 说明了如何在 AutoHotkey 中使用它的响应。
我试过这个:
MsgBox % ComObjCreate("WScript.Shell").Exec("powershell.exe -ExecutionPolicy Bypass -WindowStyle Hidden -noProfile -nologo dir").StdOut.ReadAll()
但这仍然会在很短的时间内闪烁 window。我每 25 毫秒循环一次此命令,因此让 window 闪烁通常不是有效的解决方案。
编辑:
最后得出这个最简单的解决方案:
cmd = powershell.exe -command "(Get-Process -Id " %pid% ").Threads[1].WaitReason"
shell := setup()
Loop {
string := shell.exec(cmd).stdout.readall()
...}
setup() {
detecthiddenwindows on
run %comspec% /k ,, hide useerrorlevel, pid
winwait ahk_pid %pid%,, 10
DllCall("AttachConsole", "uint", pid)
con := DllCall("CreateFile"
, "str", "CONOUT$", "uint", 0xC0000000, "uint", 7, "uint", 0, "uint", 3, "uint", 0, "uint", 0)
oshell := comobjcreate("wscript.shell")
return oshell
}
注意:将 AHK (AutoHotkey) 与外部 PowerShell 进程一起使用不适合必须 运行 每 25 毫秒 的任务,正如您自己发现的那样- 处理开销太大。
如果只需要获取目录列表,您可以使用内置的 AHK 功能,使用 Loop
command for files - see this answer.
下面的解决方案一般演示了如何运行控制台程序:
- 隐藏(不闪烁windows)
- 同步(等待退出)
- 其 输出被捕获
来自 AHK。
您不能将 ComObjCreate("WScript.Shell").Exec()
用于 运行 控制台应用程序 隐藏。
相反,虽然您可以使用 RunWait
隐藏 运行,但不能使用它来 捕获(控制台)输出。
解决方法 是:
使用
RunWait
.将输出重定向添加到(临时)文件到您的控制台程序调用。
之后用
FileRead
读取该文件的内容(并删除临时文件)。
; Get a temporary file path
tempFile := A_Temp "\" DllCall("GetCurrentProcessId") ".txt" ; "
; Run the console program hidden, redirecting its output to
; the temp. file (with a program other than powershell.exe or cmd.exe,
; prepend %ComSpec% /c; use 2> to redirect error output), and wait for it to exit.
RunWait, powershell.exe -ExecutionPolicy Bypass -WindowStyle Hidden -noProfile dir > %tempFile%,, Hide
; Read the temp file into a variable and then delete it.
FileRead, content, %tempFile%
FileDelete, %tempFile%
; Display the result.
MsgBox % content