Re: WScript.Shell.Exec().StdOut.AtEndOfStream waits for text - solution - ExecWithTimeout.wsf
- From: don.jscript.usenet@xxxxxxxxx
- Date: Tue, 29 Jan 2008 07:45:45 -0800 (PST)
On Jan 29, 10:44 am, don.jscript.use...@xxxxxxxxx wrote:
For those interested, my solution to the problem was complicated.
1. Execute the app.
2. Execute the monitor.
3. Read output from the app.
4. Read output from the monitor.
The monitor is another script. It has two parameters: the process ID
of the app to monitor, and the timeout in seconds. It uses WMI to
watch the specified process. If the process terminates, the monitor
ends. If the timeout elapses, the monitor terminates the process and
ends.
The next two posts will be the final code:
1. ExecWithTimeout.wsf: the main script.
2. ProcessTimeout.wsf: the monitor.
I'm sure this would have been much simpler in a compiled language or
dotNET. But I don't have that expertise or time to devote to learning
it.
<?xml version="1.0" ?>
<job>
<comment>
<![CDATA[
/*
ExecWithTimeout.wsf
execute a Windows command, copying stdout and stderr.
if specified timeout elapses and command is still running,
terminate the command and exit.
ExecWithTimeout <timeout> <command> <parameter>...
where
<timeout> is the maximum number of seconds to wait;
<command> is the command to run;
<parameter>... are parameters of the command, if any.
Before command is executed, each <parameter> is surrounded with
double quotes
if the parameter contains a Windows special character: &<>[]
{}^=;!'+,`~ or space.
Special cmd.exe processing using those special characters is not
supported.
ProcessTimeout.wsf is used to monitor the command and terminate it
if necessary.
ProcessTimeout.wsf should be located in the same folder as this
script.
Unable to output the executed app's output as it comes.
-=- oExecCmd.stdout.AtEndOfStream waits until there is text, or
the executed app terminates.
-=- oExecCmd.stdout.Read(1) waits until there is text, or the
executed app terminates.
-=- oExecCmd.stdout.ReadAll() waits until the executed app
terminates.
*/
]]>
</comment>
<script language="JavaScript">
<![CDATA[
////////////////////////////////////////////////////////////////////////////////
var timeoutSeconds = 0;
var cmd = "";
var stdout = WScript.StdOut;
var stderr = WScript.StdErr;
var isTerminatedPrematurely = false;
var reWindowsSpecialChars = /[&<>[\]{}^=;!'+,`~ ]/
var rePosInt = /^[0-9]+$/
////////////////////////////////////////////////////////////////////////////////
// get arguments.
var args = WScript.Arguments;
var iarg;
var arg;
if (args.length < 2) {
stderr.WriteLine("ExecWithTimeout: Too few parameters.");
WriteSyntax(stderr);
WScript.Quit();
}
// first arg is timeout number of seconds.
arg = args(0);
if (!rePosInt.test(arg)) {
stderr.WriteLine("ExecWithTimeout: First parameter must be
number of seconds before timeout.");
WriteSyntax(stderr);
WScript.Quit();
}
timeoutSeconds = parseInt(arg, 10);
// rest of args make up the command to execute.
// add quotes to the arg if has special characters.
for (iarg=1; iarg<args.length; iarg++) {
arg = args(iarg);
if (cmd.length > 0) cmd += " ";
if (reWindowsSpecialChars.test(arg)) {
cmd += "\"" + arg + "\"";
}
else {
cmd += arg;
}
}
////////////////////////////////////////////////////////////////////////////////
// execute command.
var oExecCmd = shell.Exec(cmd);
WScript.Sleep(100);
// execute ProcessTimeout monitor, same folder as
ExecWithTime.wsf.
var scriptPath = fso.GetParentFolderName(WScript.ScriptFullName);
if (scriptPath.charAt(scriptPath.length-1) != "\\") scriptPath +=
"\\";
var oExecTimeout = shell.Exec("cscript.exe /nologo "
+ "\"" + scriptPath + "ProcessTimeout.wsf\" "
+ oExecCmd.ProcessID + " " + timeoutSeconds);
// copy output.
stdout.Write(oExecCmd.StdOut.ReadAll());
stderr.Write(oExecCmd.StdErr.ReadAll());
stdout.Write(oExecTimeout.StdOut.ReadAll());
stderr.Write(oExecTimeout.StdErr.ReadAll());
// quit.
WScript.Quit();
//////////////////////////////////////////////////////////////////////
function WriteSyntax(stdout) {
stderr.WriteLine("ExecWithTimeout <timeout> <command>
<parameter>...\n"
+ " where\n"
+ " <timeout> is the maximum number of seconds to wait;
\n"
+ " <command> is the command to run;\n"
+ " <parameter>... are parameters of the command, if
any.\n");
}
//////////////////////////////////////////////////////////////////////
]]>
</script>
<object id="shell" progid="wscript.Shell"/>
<object id="fso" progid="Scripting.FileSystemObject"/>
</job>
.
- References:
- WScript.Shell.Exec().StdOut.AtEndOfStream waits for text
- From: don . jscript . usenet
- Re: WScript.Shell.Exec().StdOut.AtEndOfStream waits for text - solution
- From: don . jscript . usenet
- WScript.Shell.Exec().StdOut.AtEndOfStream waits for text
- Prev by Date: Re: WScript.Shell.Exec().StdOut.AtEndOfStream waits for text - solution
- Next by Date: Re: WScript.Shell.Exec().StdOut.AtEndOfStream waits for text - solution - ProcessTimeout.wsf
- Previous by thread: Re: WScript.Shell.Exec().StdOut.AtEndOfStream waits for text - solution
- Next by thread: Re: WScript.Shell.Exec().StdOut.AtEndOfStream waits for text - solution - ProcessTimeout.wsf
- Index(es):
Relevant Pages
|