How can I get the current active window at the time a batch script is run?

前端 未结 2 1458
难免孤独
难免孤独 2020-12-06 19:59

I have a batch script I want to run with hotkeys, and this script is supposed to make some actions in the active window (for example, creating a particular set of folders, o

相关标签:
2条回答
  • 2020-12-06 20:24

    You can lookup which process got the window in foreground using pinvoke of user32.dll. I've used this trick for system.window.forms.sendkeys method in a script:

    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
    
    0 讨论(0)
  • 2020-12-06 20:41

    For anyone looking for a non-Powershell solution, here's a batch script that uses cscript to invoke a block of JScript. The JScript creates a new child process, gets its PID, then walks up the ParentProcessID line of ancestors until it gets to explorer.exe, then returns the PID of the direct child. It ought to return the correct PID for the console window in which the script runs, even if there are multiple instances of cmd.exe or cscript.exe running.

    What can I say? I was feeling creative today.

    @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);
    
    0 讨论(0)
提交回复
热议问题