2012-03-15 240 views
4

我有一個批處理腳本,我想用熱鍵來運行,這個腳本應該在活動窗口中做一些動作(例如,創建一組特定的文件夾,或小寫文件夾內所有文件的名稱)。所以腳本需要在被調用時引用活動窗口。如何在批處理腳本運行時獲取當前活動窗口?

我試圖將別名的「開始」字段留空,但回顯%cd%始終打印「C:\ Windows \ System32」而不是當前活動窗口。

回答

9

您可以使用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 
1

爲尋找非Powershell的解決方案,這是一個使用cscript調用的JScript塊批處理腳本。 JScript創建一個新的子進程,獲取它的PID,然後走向ParentProcessID祖先行,直到到達explorer.exe,然後返回直接子進程的PID。它應該爲腳本運行的控制檯窗口返回正確的PID,即使存在多個運行cmd.execscript.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); 
相關問題