如何在批处理脚本运行时获取当前的活动窗口?

我有一个批处理脚本,我想用热键来运行,这个脚本应该在活动窗口中做一些动作(例如,创build一组特定的文件夹,或小写文件夹内所有文件的名称)。 所以脚本需要在被调用时引用活动窗口。

我试图离开别名的“开始”字段为空,但回显%cd%总是打印“C:\ Windows \ System32”而不是当前的活动窗口。

Solutions Collecting From Web of "如何在批处理脚本运行时获取当前的活动窗口?"

您可以使用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。 即使运行了多个cmd.execscript.exe实例,它也应该返回脚本运行的控制台窗口的正确PID。

我能说什么? 我今天感觉很有创意。

 @if (@a==@b) @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);