我有一個批處理腳本,我想用熱鍵來運行,這個腳本應該在活動窗口中做一些動作(例如,創建一組特定的文件夾,或小寫文件夾內所有文件的名稱)。所以腳本需要在被調用時引用活動窗口。如何在批處理腳本運行時獲取當前活動窗口?
我試圖將別名的「開始」字段留空,但回顯%cd%始終打印「C:\ Windows \ System32」而不是當前活動窗口。
我有一個批處理腳本,我想用熱鍵來運行,這個腳本應該在活動窗口中做一些動作(例如,創建一組特定的文件夾,或小寫文件夾內所有文件的名稱)。所以腳本需要在被調用時引用活動窗口。如何在批處理腳本運行時獲取當前活動窗口?
我試圖將別名的「開始」字段留空,但回顯%cd%始終打印「C:\ Windows \ System32」而不是當前活動窗口。
您可以使用user32.dll的pinvoke查找哪個進程在前臺獲得了該窗口。 我用這一招的system.window.forms.sendkeys方法的腳本:
Add-Type @"
using System;
using System.Runtime.InteropServices;
public class Tricks {
[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();
}
"@
$a = [tricks]::GetForegroundWindow()
get-process | ? { $_.mainwindowhandle -eq $a } # in my case:
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
161 7 13984 15820 91 9,75 7720 Console
爲尋找非Powershell的解決方案,這是一個使用cscript
調用的JScript塊批處理腳本。 JScript創建一個新的子進程,獲取它的PID,然後走向ParentProcessID
祖先行,直到到達explorer.exe
,然後返回直接子進程的PID。它應該爲腳本運行的控制檯窗口返回正確的PID,即使存在多個運行cmd.exe
或cscript.exe
的實例。
我能說什麼?我今天感覺很有創意。
@if (@[email protected]) @end /* JScript multiline comment
:: begin batch portion
@echo off
setlocal
for /f "delims=" %%I in ('cscript /nologo /e:Jscript "%~f0"') do (
echo PID of this console window is %%I
)
goto :EOF
:: end batch portion/begin JScript */
var oShell = WSH.CreateObject('wscript.shell'),
johnConnor = oShell.Exec('%comspec% /k @echo;');
// returns PID of the direct child of explorer.exe
function getTopPID(PID, child) {
var proc = GetObject("winmgmts:Win32_Process=" + PID);
// uncomment the following line to watch the script walk up the ancestor tree
// WSH.Echo(proc.name + ' has a PID of ' + PID);
return (proc.name == 'explorer.exe') ? child : getTopPID(proc.ParentProcessID, PID);
}
var PID = getTopPID(johnConnor.ProcessID);
johnConnor.Terminate();
// send the console window to the back for a second, then refocus, just to show off
oShell.SendKeys('%{ESC}');
WSH.Sleep(1000);
oShell.AppActivate(PID);
// output PID of console window
WSH.Echo(PID);