0

I have below code for long running command in JavaScript. This is a bit similar to this thread. However I modified the code to meet my requirements and now it doesn't seem to work. Can someone please suggest how to display 'Processing request please wait..' kind of message while running this command in the background:

<html>
<head>
<title>JavaScript Remote Exec Test</title>
<script type="text/javascript">
    function defer(func) {
        var proc = function(){
            func();
        }
    setTimeout(proc, 50);
    }

    function GetPC()
    {
        var strComputerName = "NA";
        var outObj = document.getElementById("outputText");

        try 
        {
            var getPCNameCommand = new ActiveXObject("WScript.Shell");
            var cmdPCName = getPCNameCommand.Exec("c:\\windows\\system32\\cmd.exe /c hostname");

            strComputerName = cmdPCName.StdOut.ReadAll();
        }
        catch (ex)
        {
            strComputerName = "Can't retrive PC name: " + ex;
        }

        return strComputerName; 
    }

    function LaunchApp()
    {
        var appPath = "c:\\windows\\system32\\Gpupdate.exe";
        var errormessage = appPath;
        var strResult = "";
        var strComputerName = GetPC();
        var outObj = document.getElementById("outputText");
        outObj.innerHTML = "Status: Updating group policy for " + strComputerName + "...";

        defer(UpdateGPO);
/*      try
        {
            var gpuExec = new ActiveXObject("WScript.Shell");
            var execResult = gpuExec.Exec(appPath);

            while (execResult.Status == 0) // wait for the command to finish
            {
                outObj.innerHTML = "Updating group policy. \n\n For Computer:\t" + strComputerName;
            }

            strResult = execResult.StdOut.ReadAll();
            strResult = strResult.replace(".","\n");
            outObj.innerHTML = strResult;
        }
        catch (ex)
        {
            errMsg = errormessage + " could not be launched. \n\n" + ex;
            outObj.innerHTML = errMsg;
        }   
*/
    }
    function UpdateGPO() {
    try
        {
            var gpuExec = new ActiveXObject("WScript.Shell");
            var execResult = gpuExec.Exec(appPath);

            while (execResult.Status == 0) // wait for the command to finish
            {
                //outObj.innerHTML = "Updating group policy. \n\n For Computer:\t" + strComputerName + ". Please wait...";
                sleep(5);
            }

            strResult = execResult.StdOut.ReadAll();
            strResult = strResult.replace(".","\n");
            outObj.innerHTML = strResult;
        }
    catch (ex)
        {
            errMsg = errormessage + " could not be launched. \n\n" + ex;
            outObj.innerHTML = errMsg;
        }   
    }
</script>
</head>
<body style="font-family:'Segoe UI';">
<input type="button" value="Update Group Policy" onclick="LaunchApp();"></input>
<p id="outputText">Waiting for command</p>
</body>
</html>
Community
  • 1
  • 1
SavindraSingh
  • 878
  • 13
  • 39

1 Answers1

1

Ok, let me see if I can explain what the issue here is...

        while (execResult.Status == 0) // wait for the command to finish
        {
            outObj.innerHTML = "Updating group policy. \n\n For Computer:\t" + strComputerName;
        }

JavaScript is single-threaded meaning it can only do one thing at a time. (For the moment, that is ignoring web-workers, which don't count in this answer.)

So.. you are doing a while loop, but you never give the browser a chance to 'breath' and update the execResult.Status, so what you really have is an endless loop.

There isn't enough code there for me reproduce the problem, so you'll have to handle this "guess" of a solution:

function waitForComplete() {
  // execResult is in scope...
  if (execResult.Status == 0) // wait for the command to finish
  {
    outObj.innerHTML = "Updating group policy. \n\n For Computer:\t" + strComputerName;
  } else {
    window.setTimeout(waitForComplete, 250);
  }
}


var gpuExec = new ActiveXObject("WScript.Shell");
var execResult = gpuExec.Exec(appPath);
waitForComplete();
Jeremy J Starcher
  • 23,369
  • 6
  • 54
  • 74
  • Ok.. even if we ignore those lines of code i.e. while loop block, I still can't make it work. BTW, that was the complete code included in HTML file that you can try with the complete code given above in a HTML file. – SavindraSingh May 07 '14 at 11:15