说我的程序如下
@ECHO Off
start "" "Notepad.exe"
pause
打开记事本后,Windows 焦点位于记事本上,因此我输入的任何内容都在那里,但我希望焦点返回到 cmd;这可能吗?怎么办?
我尝试运行它的具体程序如下:
@ECHO OFF
title SortV8
SETLOCAL ENABLEDELAYEDEXPANSION
cd "C:\img\Unsorted"
:SORT
FOR /R %%f IN (*.jpg *.png *.gif *.jpeg) DO (
echo Current file is: %%f
start "" "D:\Downloads\ImageGlass_Kobe_8.6.7.13_x64\ImageGlass.exe" %%f
powershell.exe -NoProfile -Command "(New-Object -ComObject WScript.Shell).AppActivate((Get-CimInstance Win32_Process -Filter \"ProcessId = $PID\").ParentProcessId)"
CHOICE /N /C 1234 /M "PICK A NUMBER (1 (Photo), 2 (Video), or 3(Delete), 4 (Terminate Program)"%1
IF ERRORLEVEL 4 goto END
IF ERRORLEVEL 3 echo "To the trash it goes!" && move %%f "C:\img\Delete"
IF ERRORLEVEL 2 echo "Video" && move %%f "C:\img\Videos"
IF ERRORLEVEL 1 echo "Photo" && move %%f "C:\img\Photos"
taskkill /IM ImageGlass.exe
cls
GOTO SORT
)
:END
taskkill /IM ImageGlass.exe
cls
echo "Goodbye!"
pause
:eol
您可以通过其 CLI 使用 PowerShell 重新激活控制台窗口,但请注意,执行开销并非微不足道。
注意:该解决方案并不完全稳健,但在实践中可能效果很好:
@ECHO Off
:: Asynchronously launch Notepad, which steals the focus
:: (Notepad becomes the active window).
start "" "Notepad.exe"
:: Reactivate this console window with the help of PowerShell.
powershell.exe -NoProfile -Command "(New-Object -ComObject WScript.Shell).SendKeys('%%{tab}')"
pause
上面模拟了用户输入,即按下 Alt-Tab 按键,以重新激活当前控制台窗口。 这依赖于:
记事本的窗口已经被激活(考虑到调用
powershell.exe
的执行开销,这很可能)
用户在批处理文件运行时未手动激活其他窗口。
以下变体更健壮,但有一个不太可能满足的先决条件:
它不是发送击键,而是尝试通过其进程 ID 重新激活当前控制台窗口。
但是,仅当当前操作系统使用会话中的
SPI_GETFOREGROUNDLOCKTIMEOUT
WinAPI 函数 WinAPI 函数报告的有效 SystemParametersInfo
值是 0
时,此程序化窗口激活才会成功,而这种情况不是默认。
虽然原则上可以根据需要使用PowerShell代码将此值设置为0
(请参阅此答案),但从
cmd.exe
(批处理文件)执行此类代码会莫名其妙地失败并显示
Access denied
错误(而直接执行相同的代码工作正常从PowerShell) - 我还没有找到解决这个问题的方法(如果有人有解释或解决方案,请告诉我们)。
- 一旦在会话中运行,它本身就会将该值设置为 0
,因此,如果您碰巧有一个登录时运行的 AutoHotkey 脚本(无论什么)确实如此),下面的代码
将会工作。也就是说,如果您已经安装了 AutoHotkey,您可以尝试使用特定的 AutoHotkey 脚本来解决手头的问题。
@ECHO Off
:: Asynchronously launch Notepad, which steals the focus
:: (Notepad becomes the active window).
start "" "Notepad.exe"
:: !! SEE LIMITATION DISCUSSED ABOVE
:: Reactivate this console window with the help of PowerShell.
powershell.exe -NoProfile -Command "$null = (New-Object -ComObject WScript.Shell).AppActivate((Get-CimInstance Win32_Process -Filter \"ProcessId = $PID\").ParentProcessId)"
pause