Over the years, I have seen many different techniques for emulating the InputBox and MsgBox functions in JScript, but none of them were quite as elegant as the one I saw here. Once I dug into the code and realized that ScriptControl was making it so that JScript could run VBScript commands, I felt a whole new world of possibilities had been found. Therefore, my first test was to make a better functioning InputBox and MsgBox function available to JScript by using the following code:


(function(vbe) {
  vbe.Language = "VBScript";
  vbe.AllowUI = true;

  var constants = "OK,Cancel,Abort,Retry,Ignore,Yes,No,OKOnly,OKCancel,AbortRetryIgnore,YesNoCancel,YesNo,RetryCancel,Critical,Question,Exclamation,Information,DefaultButton1,DefaultButton2,DefaultButton3".split(",");
  for(var i = 0; constants[i]; i++) {
    this["vb" + constants[i]] = vbe.eval("vb" + constants[i]);
  }

  InputBox = function(prompt, title, msg, xpos, ypos) {
    return vbe.eval('InputBox(' + [
        toVBStringParam(prompt),
        toVBStringParam(title),
        toVBStringParam(msg),
        xpos != null ? xpos : "Empty",
        ypos != null ? ypos : "Empty"
      ].join(",") + ')');
  };

  MsgBox = function(prompt, buttons, title) {
    return vbe.eval('MsgBox(' + [
        toVBStringParam(prompt),
        buttons != null ? buttons : "Empty",
        toVBStringParam(title)
      ].join(",") + ')');
  };

  function toVBStringParam(str) {
    return str != null ? 'Unescape("' + escape(str + "") + '")' : "Empty";
  }
})(new ActiveXObject("ScriptControl"));

What makes this code better is the fact that it will accept any string (even those with special characters). It is also better because it allows for null parameters to be passed to the VBScript functions. Finally, this script makes all of the MsgBox constants such as vbRetryCancel and vbInformation available. The following are example calls made to the defined functions:


var name = InputBox('I am "Script-101".\nWhat is your name?', "Name");
var greetings = name
  ? 'Nice to meet you "' + name + '".'
  : "That's fine, you don't have to tell me who you are.";
MsgBox(greetings, name ? vbInformation : vbCritical, "Greetings");

You can download the JScript file that contains these two code blocks and then try to run it on your Windows PC.  If you are running a 32bit system, this script will work as expected. On the other hand, if you are running a 64bit version of Windows, this script will error out with the message “Automation server can’t create object”.  The reason for this is that “ScriptControl”, which is being used to allow JScript to call VBScript functions, isn’t available in the 64bit version of cscript or WScript.  Therefore, to run this script, you will have to do so using the 32bit version.  You can do this by doing the following:

  1. Go to the start menu
  2. If you are not using Windows Seven, click “Run”
  3. type %windir%\SysWoW64\cmd.exe
  4. Click OK
  5. Now type cscript /path/to/the/script.vbs (change the path to whatever the path to the script is)
Categories: BlogJScriptVBScript

7 Comments

ildar · March 12, 2012 at 9:01 PM

Hi Chris,

This is good continuation of the investigation started in my article. Your report on issues with special characters in arguments are very appreciable. I will fix them shortly.

And here are my five cents to your contribution. These lines from 6 through 8 would be considered better if they would be as follows:

[code language=javascript]
for(var i = 0; constants[i]; i++) {
var c = 'vb' + constants[i];
this[c] = vbe.eval(c);
}
[/code]

    Chris West · March 12, 2012 at 11:53 PM

    Good catch! I changed my code appropriately. I decided not to add the extra variable but I did remove the JScript eval function.

Rachael · September 22, 2016 at 3:24 AM

Hey Chris. I just wanted you to know this script was incredibly useful – and using your tips, I managed to make a hybrid 3-language script within a single file that others may find useful. The code is here:

The useful thing about this method is it will run on both 32-bit and 64-bit systems – as it adds in syswow64 into your path temporarily before running cscript.

@if (@this==@isBatch) @then
@echo off
setlocal enableextensions

rem -- force use 32-bit cscript
set path=%windir%\syswow64;%path%

cscript //nologo //e:jscript "%~f0" %*

endlocal

exit /b
@end

(function(vbe) {
vbe.Language = "VBScript";
vbe.AllowUI = true;

var constants = "OK,Cancel,Abort,Retry,Ignore,Yes,No,OKOnly,OKCancel,AbortRetryIgnore,YesNoCancel,YesNo,RetryCancel,Critical,Question,Exclamation,Information,DefaultButton1,DefaultButton2,DefaultButton3".split(",");
for(var i = 0; constants[i]; i++) {
this["vb" + constants[i]] = vbe.eval("vb" + constants[i]);
}

InputBox = function(prompt, title, msg, xpos, ypos) {
return vbe.eval('InputBox(' + [
toVBStringParam(prompt),
toVBStringParam(title),
toVBStringParam(msg),
xpos != null ? xpos : "Empty",
ypos != null ? ypos : "Empty"
].join(",") + ')');
};

MsgBox = function(prompt, buttons, title) {
return vbe.eval('MsgBox(' + [
toVBStringParam(prompt),
buttons != null ? buttons : "Empty",
toVBStringParam(title)
].join(",") + ')');
};

function toVBStringParam(str) {
return str != null ? 'Unescape("' + escape(str + "") + '")' : "Empty";
}
})(new ActiveXObject("ScriptControl"));

var name = InputBox('I am "Script-101".\nWhat is your name?', "Name");
var greetings = name
? 'Nice to meet you "' + name + '".'
: "That's fine, you don't have to tell me who you are.";
MsgBox(greetings, name ? vbInformation : vbCritical, "Greetings");

lllaffer · June 1, 2022 at 4:33 AM

Thank you Chris – this is JScript-poetry!

Another 5 cents:

Because the Inputbox appears in upper left corner until set proper xpos & ypos ,
because twips are hard to calculate … and because the defaults should fit the average desire, I changed InputBox to

InputBox = function(prompt, title, dflt, xpos, ypos) {
var pos=[xpos, ypos];
if (xpos == null && ypos != null) pos = [ 0, ypos ];
if (xpos != null && ypos == null) pos = [ xpos ];
if (xpos == null && ypos == null) pos = [];

return vbe.eval(‘InputBox(‘ + [
toVBStringParam(prompt),
toVBStringParam(title),
toVBStringParam(dflt)
].concat(pos).join(“,”) + ‘)’);
};

thnx for your work

What is the C# version of VB.net's InputDialog? - QuestionFocus · January 8, 2018 at 1:02 AM

[…] See these for further information: ScriptControl MsgBox in JScript Input and MsgBox in JScript […]

[C#] What is the C# version of VB.NET's InputBox? - Pixorix · June 8, 2023 at 5:42 AM

[…] See these for further information: ScriptControl MsgBox in JScript Input and MsgBox in JScript […]

Leave a Reply

Your email address will not be published. Required fields are marked *