Как получить текущее активное окно во время запуска пакетного скрипта? - PullRequest
4 голосов
/ 15 марта 2012

У меня есть пакетный сценарий, который я хочу запустить с помощью горячих клавиш, и этот сценарий должен выполнять некоторые действия в активном окне (например, создавать определенный набор папок или использовать строчные буквы для всех имен файлов внутри папки) , Поэтому сценарий должен ссылаться на активное окно при его вызове.

Я пытался оставить поле «Начало в» псевдонима пустым, но эхо% cd% всегда печатает «C: \ Windows \ System32» вместо текущего активного окна.

Ответы [ 2 ]

13 голосов
/ 15 марта 2012

Вы можете посмотреть, какой процесс получил окно на переднем плане, используя pinvoke из user32.dll.Я использовал этот трюк для метода 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
2 голосов
/ 17 декабря 2014

Для тех, кто ищет решение не от Powershell, вот пакетный скрипт, который использует cscript для вызова блока JScript.JScript создает новый дочерний процесс, получает его PID, затем идет по линии ParentProcessID предков, пока не достигнет explorer.exe, а затем возвращает PID прямого дочернего процесса.Он должен возвращать правильный PID для окна консоли, в котором выполняется скрипт, даже если запущено несколько экземпляров cmd.exe или cscript.exe.

Что я могу сказать?Я чувствовал себя творческим сегодня.

@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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...