SavindraSingh
SavindraSingh

Reputation: 961

Long running task in JavaScript

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>

Upvotes: 0

Views: 448

Answers (1)

Jeremy J Starcher
Jeremy J Starcher

Reputation: 23873

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();

Upvotes: 1

Related Questions