1

I am looking for a way to wait for a vbscript to finish execution before continuing to execute java code. I have a process call the script, which works fine, and a waitFor() to stop execution until it completes. The problem is that the script restarts itself with admin privileges upon start up. Since the process finishes when it restarts itself, the script doesn't have time to execute before my program continues.

Is there any way to have the program wait for this elevated script to run, or to start the script in such a way that it doesn't need to be restarted with elevated rights?

This is how I elevate the script

If Not WScript.Arguments.Named.Exists("elevate") Then
CreateObject("Shell.Application").ShellExecute WScript.FullName _
, """" & WScript.ScriptFullName & """ /elevate //nologo" , "", "runas", 1
WScript.Quit
End If

This is how I call and wait for the process.

Process child = Runtime.getRuntime().exec("cscript 
C:\\some\\path\\name\\scriptName.vbs");
child.waitFor();

Thanks in advance

astorms
  • 13
  • 3

2 Answers2

0

Simple: use two different scripts!

The first one is started by the Java code. That script starts the second script with elevated permissions. And waits for the second script to finish.

Then Java will continue when effectively both scripts are done!

Otherwise you would need to implement some other (complicated!) way for the single script to send "signals" to another JVM thread. Complicated and easy to get wrong.

Regarding your question how to do that: see here for example.

GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • Thanks, I am exploring this option right now. Do you know of any resources where I might find out how to run one script from another, and how to wait for it to finish and return a string with its status? I am new to vbscripts and have been piecing them together slowly. – astorms Aug 23 '17 at 18:01
  • See my updated answer (and hint: google has such answers for you, too) – GhostCat Aug 23 '17 at 18:13
  • I cant find a way to run it elevated and wait for it to complete from the first script. – astorms Aug 23 '17 at 20:59
0

I had the same problem, execute a VBA script from Java and wait until it's finished:

  Runtime.getRuntime().exec(new String[]{"C:\\Windows\\System32\\wscript.exe", "C:/macro.vbs"});

The Macro contains a VBS code that is running a Macro (generateOutputFiles) inside an excel file:

Set objExcel = CreateObject("Excel.Application")
Set objWorkbook = objExcel.Workbooks.Open("C:\excel\test.xls")
objExcel.Application.EnableEvents = False
objExcel.Application.DisplayAlerts = False
objExcel.Application.Run "test.xls!generateOutputFiles"
objExcel.ActiveWorkbook.Save
objExcel.ActiveWorkbook.Close

After a long and painful research, I have decided to create a flag on the VB script itself after the end of its main program and wait for it in Java code as follows:

In VBA:

Set objExcel = CreateObject("Excel.Application")
Set objFSO = CreateObject("Scripting.FileSystemObject")
' Delete the exesting end execution flag
endLoadingFlagPath = "C:\excel\LOADING_END_FLAG"
If (objFSO.FileExists(endLoadingFlagPath)) Then
   objFSO.DeleteFile endLoadingFlagPath
End If

Set objExcel = CreateObject("Excel.Application")
Set objWorkbook = objExcel.Workbooks.Open("C:\excel\test.xls")
objExcel.Application.EnableEvents = False
objExcel.Application.DisplayAlerts = False
objExcel.Application.Run "test.xls!generateOutputFiles"
objExcel.ActiveWorkbook.Save
objExcel.ActiveWorkbook.Close
' Create the end execution flag right after the main VB program
Set objFile = objFSO.CreateTextFile(endLoadingFlagPath)

In Java:

import java.io.File;
import java.util.concurrent.TimeUnit;

import org.apache.log4j.Logger;



public class Test {

private static final Logger logger = Logger.getLogger("SCRIPT_RUNNER");

    public void executeVBScript() throws Exception {
        Runtime.getRuntime().exec(new String[]{"C:\\Windows\\System32\\wscript.exe", "C:/macro.vbs"});
        waitLoadingFinished();
    }

    private void waitLoadingFinished() throws Exception {
        File endLoadingFlagFile = new File("C:\\excel\\LOADING_END_FLAG");
        for(int attempt = 0; attempt < 10; attempt++) {
            utilSetDelay(5);
            if(endLoadingFlagFile.exists()) {
                return;
            }
        }
        throw new Exception("Timeout waiting for task");
    }

    private void utilSetDelay(long seconds) {
        try {
            TimeUnit.SECONDS.sleep(seconds);
        } catch(Exception ex) {
            logger.warn("Cannot sleep:" + ex.getMessage());
        }
    }
}

The attempt count and sleep delay can be set as parameters.

Shessuky
  • 1,846
  • 21
  • 24