Wajo357
Wajo357

Reputation: 91

wshShell and WMIC working together in batch?

I was trying to create a scrollable list for a batch file using the method found here: Scrollable Lists in .bat Files Credit to https://stackoverflow.com/users/778560/aacini

One I tried adding back in my code for my regular batch a few lines at a time, I noticed that the solution doesn't work when I use WMIC. What is the reason for this and is there an easy solution? You can run the below code and then un-comment the WMIC line and see it will not work anymore.

Edit: I am using Windows 7

Thanks!

@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}");
}

Upvotes: 3

Views: 249

Answers (1)

JosefZ
JosefZ

Reputation: 30183

SendKeys Method sends one or more keystrokes to the active window. Unfortunately, Sendkeys() sometimes fails usually due to focus or timing, both troublesome and difficult to solve problems. I tried pause and timeout, tried WshShell.AppActivate in various combinations, all without success…

Finally, I found culprit in clearing previous doskey history via doskey /REINSTALL command: it installs a new copy of doskey. I can recommend more intuitive (and less invasive) method to clear the doskey command history buffer:

doskey /ListSize=0
doskey /ListSize=50

Bonus: FOR loops explanation.

  • outer %%A loop to retrieve the name property;
  • inner %%a loop to remove the ending carriage return in the value returned: wmic behaviour: each output line ends with 0x0D0D0A (<CR><CR><LF>) instead of common 0x0D0A (<CR><LF>).

Credit: Dave Benham's WMIC and FOR /F: A fix for the trailing <CR> problem

Working script (Windows 8.1 64 bit):

@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}");
}

Upvotes: 1

Related Questions