wshShell 和 WMIC 一起批量工作?

wshShell and WMIC working together in batch?

我试图使用此处找到的方法为批处理文件创建一个可滚动列表:Scrollable Lists in .bat Files 感谢 https://whosebug.com/users/778560/aacini

我尝试在我的常规批处理代码中一次添加几行,我注意到当我使用 WMIC 时该解决方案不起作用。这是什么原因,是否有简单的解决方案?您可以 运行 下面的代码,然后取消注释 WMIC 行,您会发现它不再起作用了。

编辑:我正在使用 Windows 7

谢谢!

@if (@CodeSection == @Batch) @then
@echo off
setlocal EnableDelayedExpansion
color F0


::FOR /F "tokens=2 delims==" %%A IN ('WMIC csproduct GET Name /VALUE ^| FIND /I "Name="') DO SET machine=%%A


Echo Reset or Continue
Set MenuOptions=RESET Continue
call :ShowMenu

pause
exit

:ShowMenu
set numOpts=0
for %%a in (%MenuOptions%) do (
   set /A numOpts+=1
   set "option[!numOpts!]=%%a"
)
rem Clear previous doskey history
doskey /REINSTALL
rem Fill doskey history with menu options
cscript //nologo /E:JScript "%~F0" EnterOpts
for /L %%i in (1,1,%numOpts%) do set /P "var="

rem Send a F7 key to open the selection menu
cscript //nologo /E:JScript "%~F0"
set /P "MenuSelected=Option Selected: "
echo/
@end
var wshShell = WScript.CreateObject("WScript.Shell"),
    envVar = wshShell.Environment("Process"),
    numOpts = parseInt(envVar("numOpts"));

if ( WScript.Arguments.Length ) {
   // Enter menu options
   for ( var i=1; i <= numOpts; i++ ) {
      wshShell.SendKeys(envVar("option["+i+"]")+"{ENTER}");
   }
} else {
   // Enter a F7 to open the menu
   wshShell.SendKeys("{F7}");
}

SendKeys Method 发送一次或多次击键 到活动 window。不幸的是,Sendkeys()有时会失败,通常是由于focustiming,既麻烦又难以解决的问题。我尝试了 pausetimeout,尝试了 WshShell.AppActivate 的各种组合,都没有成功……

最后,我找到了通过 doskey /REINSTALL 命令清除以前 doskey 历史记录的罪魁祸首:它安装了 doskey 的新副本。我可以推荐更直观(侵入性更小)的方法来清除 doskey 命令历史缓冲区:

doskey /ListSize=0
doskey /ListSize=50

奖励:FOR 循环解释。

  • 外部 %%A 循环检索 name 属性;
  • 内部 %%a 循环删除值 returned: wmic 中结束的 carriage return 行为:每个输出行以 0x0D0D0A (<CR><CR><LF>) 而不是常见的 0x0D0A (<CR><LF>).
  • 结尾

图片来源:Dave Benham WMIC and FOR /F: A fix for the trailing <CR> problem

工作脚本(Windows 8.1 64 位):

@if (@CodeSection == @Batch) @then
@echo OFF
setlocal EnableDelayedExpansion
REM color F0

  FOR /F "tokens=2 delims==" %%A IN ('
    WMIC csproduct GET Name /VALUE ^| FIND /I "Name="
  ') DO FOR %%a in ("%%~A") DO SET "_machine=%%~a"

Echo Reset or Continue %_machine%
Set "MenuOptions=%_machine% RESET Continue"  expanded merely for debugging purposes
call :ShowMenu

REM pause
exit /B

:ShowMenu
set numOpts=0
for %%a in (%MenuOptions%) do (
   set /A numOpts+=1
   set "option[!numOpts!]=%%a"
)
rem Clear previous doskey history
REM this causes problems: doskey /REINSTALL
doskey /ListSize=0
doskey /ListSize=50
rem Fill doskey history with menu options
cscript //nologo /E:JScript "%~F0" EnterOpts
for /L %%i in (1,1,%numOpts%) do set /P "var="

rem Send a F7 key to open the selection menu
cscript //nologo /E:JScript "%~F0"
set /P "MenuSelected=Option Selected: "
echo/
goto :eof
@end
var wshShell = WScript.CreateObject("WScript.Shell"),
    envVar = wshShell.Environment("Process"),
    numOpts = parseInt(envVar("numOpts"));

if ( WScript.Arguments.Length ) {
   // Enter menu options
   for ( var i=1; i <= numOpts; i++ ) {
      wshShell.SendKeys(envVar("option["+i+"]")+"{ENTER}");
   }
} else {
   // Enter a F7 to open the menu
   wshShell.SendKeys("{F7}");
}