Running 32bit dependent scripts in a 64bit world


As seen earlier, it can be problematic to run scripts which rely on 32bit COM objects on a 64bit platform. To make things easier, I wrote basic some script code to detect that the wrong scripting host was run and fork out to the correct one. This just uses a variation of the "detect cscript vs. wscript" pattern, but instead we look at the current processor and do a check to see if we are running the wrong flavor of the script host.


 



//


// this script code relies on 32bit COM objects, if we are running on


// a 64bit system we will want to run under WOW64 (the x86 emulator).


//


 


var shell = WScript.CreateObject("WScript.Shell");


var cpu = shell.ExpandEnvironmentStrings("%PROCESSOR_ARCHITECTURE%").toLowerCase();


var host = WScript.FullName.toLowerCase();


 


// check to see if we are on an AMD64 processor and running the


// wrong version of the scripting host.


if(host.indexOf("system32") != -1 && cpu == "amd64")


    {


    var syswow64Host = host.replace(/system32/g, "syswow64");


    var newCmd = syswow64Host + " \"" +


        WScript.ScriptFullName + "\" //Nologo";


 


    // ATTEMPT to pass all the same command


    //  line args to the new process


    var args = WScript.Arguments;


    for(i=0; i<args.length; i++)


        newCmd += " " + args(i);


 


    WScript.Echo("Running the syswow64 bit version instead...\n  " +


        newCmd + "\n");


 


    // launch the new script and echo all the output


    var exec = shell.Exec(newCmd);


    while(exec.Status == 0)


        {


        if(!exec.StdOut.AtEndOfStream)


            WScript.Echo(exec.StdOut.ReadAll());


        WScript.Sleep(100);


        }


 


    if(!exec.StdOut.AtEndOfStream)


        WScript.Echo(exec.StdOut.ReadAll());


 


    WScript.Quit(exec.ExitCode);


    }


 


// the real script code goes here ...


 


WScript.Echo("done");


 


In this sample we are just checking for AMD64, so you may want to add logic for Itanium or other platforms as well.


 


Be sure to notice the "ATTEMPT" comment when transposing the command line options from the current process into the new one. The way that the command shell handles double quotes makes it hard to reproduce the exact command line from the support we have in script. For example, if you pass /abc="hello world" as an argument, the quotes will get stripped out and you will actually see /abc=hello world from your script code. If we pass this raw argument (as shown above) into the new process then the one argument will be interpreted as two because of the missing quotes. It is left as a reader exercise to detect spaces and reconstruct the exact arguments if needed.


 


 

Comments (1)
  1. We used this to deal with wscript vs cscript restarts:

    Function RestartWithCScript()

     Dim strCMD

     Dim iCount

     strCMD = "Cscript " & Chr(34) & Wscript.ScriptFullName & Chr(34)

     If Wscript.Arguments.Count > 0 Then

      For iCount = 0 To Wscript.Arguments.Count – 1

        ‘Add Argument

        ‘Check for no spaces

        if Instr(Wscript.Arguments(iCount), " ") = 0 then

          strCMD = strCMD & " " & Wscript.Arguments(iCount) & " "

        Else

          ‘Has spaces – need to either quote it or split and quote it

          If Instr("/-", Left(Wscript.Arguments(iCount), 1)) > 0 Then

            ‘Split at first = or :

             If Instr(Wscript.Arguments(iCount),"=") > 0 Then

               strCMD = strCMD & " " & Left(Wscript.Arguments(iCount), Instr(Wscript.Arguments(iCount), "=") ) & """" & Mid(Wscript.Arguments(iCount), Instr(Wscript.Arguments(iCount), "=") + 1) & """ "

             ElseIf Instr(Wscript.Arguments(iCount),":") > 0 Then

                 strCMD = strCMD & " " & Left(Wscript.Arguments(iCount), Instr(Wscript.Arguments(iCount), ":") ) & """" & Mid(Wscript.Arguments(iCount), Instr(Wscript.Arguments(iCount), ":") + 1) & """ "

             Else

               ‘Just quote the whole thing

               strCMD = strCMD & " """ & Wscript.Arguments(iCount) & """ "

             End if

          Else

            strCMD = strCMD & " """ & Wscript.Arguments(iCount) & """ "

          End if

        End if

      Next

     End If

     WshShell.Run strCMD, 1, False

    End Function

    I’m sure it could be modified for this.

Comments are closed.

Skip to main content