4

In a batch file I can get the following to give me a message box with an 'ok' button

mshta.exe vbscript:Execute^("msgbox ""Registers NOT submitted""& VbCrLf & VbCrLf &""Tap or click 'Ok' to exit"",vbexclamation,""Please check your internet connection"":close"^)

I can add yes no buttons thus;

mshta.exe vbscript:Execute^("msgbox ""Registers NOT submitted""& VbCrLf & VbCrLf &""Tap or click 'Ok' to exit"",VBYesNo,""Please check your internet connection"":close"^)

What I need to do is to route the path of the rest of the script depending on which button they pressed - yes / no. Is this possible without referencing an external .vbs?

Many thanks.

Gideon
  • 43
  • 5

2 Answers2

0

Not easily, no. The HTA implementation of neither VBScript nor JScript offers a native way to produce an exit code. You could possibly find the process object corresponding to the HTA instance then use that object's .Terminate method to exit non-zero (as demonstrated in this answer); or possibly have the HTA conditionally write a temporary file or store a registry value. But all of those choices involve leaving the world of the graceful one-liner and you might as well use a hybrid script which does recognize commands to exit non-zero.

If a tidy one-liner is what you're after, you might have better luck with PowerShell:

powershell "add-type -As System.Windows.Forms; exit([windows.forms.messagebox]::show(\"Registers NOT submitted.`n`nDo you want to continue?\",'Warning',4))"

That will exit status 6 for "Yes", 7 for "No". So basically...

if errorlevel 7 (
    rem // user chose "No"
    exit /b
) else (
    rem // user chose "Yes"
    goto begin
)

The argument of "4" in that [windows.forms.messagebox]::show method can be any of the following values:

0 -- OK
1 -- OK Cancel
2 -- Abort Retry Ignore
3 -- Yes No Cancel
4 -- Yes No
5 -- Retry Cancel

The buttons result in the following exit codes:

OK = errorlevel 1
Cancel = errorlevel 2
Abort = errorlevel 3
Retry = errorlevel 4
Ignore = errorlevel 5
Yes = errorlevel 6
No = errorlevel 7
Community
  • 1
  • 1
rojo
  • 24,000
  • 5
  • 55
  • 101
0

The only way I can think of is to use a temporary file that holds the index of the clicked button.

Since this extends also the VBScript portion (due to the file creation code), I decided to place it in the batch script directly after the batch code. To identify it, every line is preceded with //. (Regard that line continuation _ cannot be used there; environment variables like %TEMP% cannot be used also.)

In the batch script portion, the VBScript lines are read by findstr /R "^//" and a for /F loop, all lines of the VBScript code are appended to each other, using separator :. (Regard the limitation of command line length of about 8190 characters, which must not be exceeded by the entire VBScript.)

After having executed the mshta VBScript:Execute^("!SCRIPT!"^) command line, the index of the clicked MsgBox button is read from the temporary file (which is deleted immediately afterwards). Then the button name is displayed and the ErrorLevel is set to the button index just for demonstration.

So here is the full code including some explanatory comments (save it with extension .bat or cmd):

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem /* Define constants here: */
set "BUTTON[1]=OK"
set "BUTTON[2]=Cancel"
set "BUTTON[3]=Abort"
set "BUTTON[4]=Retry"
set "BUTTON[5]=Ignore"
set "BUTTON[6]=Yes"
set "BUTTON[7]=No"

rem /* Read VBScript portion which is everything with leading `//`
rem    (see the very bottom of this batch file): */
set "SCRIPT=" & set "SEP="
for /F "delims=" %%L in ('findstr /R "^//" "%~f0"') do (
    set "LINE=%%L"
    setlocal EnableDelayedExpansion
    set "LINE=!LINE:*//=!"
    set ^"LINE=!LINE:^"=""!^" & rem "
    for /F delims^=^ eol^= %%S in ("!SCRIPT!!SEP!!LINE!") do (
        endlocal
        set "SCRIPT=%%S"
        setlocal EnableDelayedExpansion
    )
    endlocal
    set "SEP=: "
)

rem /* Execute VBScript here in the parent directory of this batch file;
rem    this directory is going to contain a temporary text file then: */
setlocal EnableDelayedExpansion
cd /D "%~dp0"
mshta VBScript:Execute^("!SCRIPT!"^)
endlocal

rem /* Read the button index from the temporary text file and display: */
< "%~dp0msgbox_return_button.txt" set /P "INDEX="
del "%~dp0msgbox_return_button.txt"
call echo Button %%BUTTON[%INDEX%]%% ^(%INDEX%^) has been pressed.

rem /* Set `ErrorLevel` to the button index just as an example: */
cmd /C exit %INDEX%

endlocal
exit /B


/* VBScript */

//Set objFSO = CreateObject("Scripting.FileSystemObject")
//Set objTXT = objFSO.CreateTextFile(objFSO.BuildPath(objFSO.GetAbsolutePathName("."), "msgbox_return_button.txt"), True)
//objTXT.WriteLine(MsgBox("Please let me know:" & vbCrLf & "Is my answer helpful?", vbYesNo + vbQuestion, "StackOverflow"))
//objTXT.Close
//Close
aschipfl
  • 33,626
  • 12
  • 54
  • 99
  • Thank you for spending time on helping to find a solution - I really appreciate the time and trouble you have taken! – Gideon Jun 24 '16 at 19:30