2012-03-15 11 views
4

私はホットキーで実行したいバッチスクリプトを持っています。このスクリプトは、アクティブなウィンドウでいくつかのアクションを行うことが想定されています(たとえば、特定のフォルダセットを作成するか、フォルダ内のファイルのすべての名前を小文字にします)。だから、スクリプトは呼び出されたときにアクティブなウィンドウを参照する必要があります。バッチスクリプトの実行時に現在アクティブなウィンドウを取得するにはどうすればよいですか?

エイリアスの「開始」フィールドは空白にしておきますが、%cd%をエコー表示すると、常に現在のアクティブなウィンドウではなく「C:\ Windows \ System32」と表示されます。

答えて

9

user32.dllのpinvokeを使用して、フォアグラウンドでウィンドウを取得したプロセスを検索できます。 私はスクリプトでsystem.window.forms.sendkeys方法については、このトリックを使用しました:非PowerShellのソリューションを探している人のために

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

、ここでのJScriptのブロックを呼び出すためにcscriptを使用するバッチスクリプトです。 JScriptは新しい子プロセスを作成し、そのPIDを取得し、次にexplorer.exeになるまで祖先のParentProcessID行を歩き、直接の子のPIDを返します。 cmd.exeまたはcscript.exeの複数のインスタンスが実行中であっても、スクリプトが実行されるコンソールウィンドウの正しいPIDを返す必要があります。

私は何と言うことができますか?今日私は創造的な気分でした。

@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); 
関連する問題