I was excited about WSH 2.0 b2's support for stdin until I saw the
limitations of the implementation, which leave me with a problem that I need
to solve, that I haven't solved yet.
Please read on past my WSH suggestions for a description of where I'm stuck.
Thanks. ;-)
What's there now is great for including cscript's in chains of commands.
NOW what I need is Std{In,Out,Err} at the WshShell level. Something like:
WshShell.RunStdIn=SomeOpenFSO-be-it-our-stdin-or-a-file-we-opened
WshShell.RunStdOut=SomeOpenFSO-be-it-our-stdout-or-a-file-we-opened
WshShell.Run cmd
Or maybe, to be most flexible, and to avoid imposing interactive syntax like
| on the operation, let's create a CommandList (see, we won't even call it a
pipe):
MyCL=WshShell.CommandList
MyCL.Clear
MyCL.Stdin=SomeOpenFSO-be-it-our-stdin-or-a-file-we-opened
CLItem=MyCL.Add("prog1")
CLItem=MyCL.Add("prog2")
CLItem=MyCL.Add("prog3")
MyCL.Stdout=SomeOpenFSO-be-it-our-stdin-or-a-file-we-opened
WshShell.Run MyCL, [wait true/false], [window style]
' Yes, this implies that everything in the list of piped stuff is run with
wait; if it's not, it's
' not useful for being piped anyway; the only thing that could be async
would be the
' invocation of the entire pipe itself from the code that created it, if
desired; window style
' is a little strange. I guess one could have a property on a CLItem
specifying window
' style for that particular pipe item. It also implies every process's
stdout is passed to the
' next process's stdin. I suppose one could also have
CLItem.ForwardStdout=true (default)
' and CLItem.ForwardStderr=true (not default) properties to choose whether
stderr or stdout
' or both get forwarded. It also implies that a command list gets hooked
together in order
' of the Add's, which might not be bright. Maybe CLItem.NextItem would be a
useful
' property, allowing one to include/exclude commands in a list, on the fly.
Anyway, back out of fantasyland into reality, ALLIWANNADO is:
1. Use cscript to set a bunch of environment variables for a legacy app.
2. Run that legacy app, piping an existing text file into it as stdin.
And I can't figure out a way, even combining .vbs and .bat files, to get
this to work. What I've run into is:
1. If I WshShell.Run "e:\legacy\prog.exe < c:\indata.txt" I get the message
"Invalid file name in command line".
2. If I WshShell.Run "e:\mybatch.bat" into which I've put the above command
line, none of the environment variables I so carefully set in my script
prior to the WshShell.Run, are available in that batch file's environment.
I don't want to write a custom .bat file out for each invocation of the app
with a bunch of set's and the e:\legacy\prog.exe invocation, then .Run that
HELP?
Thanks,
--
* Helen *
he...@comteck.com
Maybe something like this will work for you ...
Set WSHShell = WScript.CreateObject("WScript.Shell")
Set ofs = WScript.CreateObject("Scripting.FileSystemObject")
TempName = WshShell.Environment("PROCESS").Item("TEMP")
TempName = TempName & "\~" & ofs.GetTempName & ".bat"
Set otf = ofs.OpenTextFile(TempName, 2, True)
otf.WriteLine "set Var1=Whatever"
otf.Writeline "set Var2=Something else"
otf.Writeline "e:\legacy\prog.exe < c:\indata.txt"
otf.Write "del " & TempName
otf.Close
ReturnValue = WSHShell.Run ("%comspec% /c " & TempName, 0, True)
Change the zero in the last line to one to reveal the DOS window of the
running program.
This approach can be run from Wscript.exe and doesn't use the new
console support available only in the version 2.0 beta.
Tom Lavedas
-----------
http://www.pressroom.com/~tglbatch/
*****************************mytest.vbs************************************
Set Argc = Wscript.Arguments
Set Argv = Wscript.Arguments
If Argc.Count Then
WSHShell.Popup Argc.Item(0) & sMsg, 1, "Notice", 64
WSHShell.Popup Argc.Item(1) & sMsg, 1, "Notice", 64
WSHShell.Popup Argv.Item & sMsg, 1, "Notice", 64
On Error Resume Next
Else
On Error Resume Next
Err.Raise 1 ' Raise an overflow error.
Wscript.Echo "No Var Passed"
Err.Clear ' Clear the error
Wscript.Quit()
End If
Tom Lavedas <lav...@pressroom.com> wrote in message
news:379CA5...@pressroom.com...
> Helen C. O'Boyle wrote:
> > Anyway, back out of fantasyland into reality, ALLIWANNADO is:
> > 1. Use cscript to set a bunch of environment variables for a legacy
app.
> > 2. Run that legacy app, piping an existing text file into it as stdin.
> Maybe something like this will work for you ...
Yes! It did. I hit that solution early in the morning, actually. Seeing
that someone else went that far in search of a solution to this one is good
feedback that it might well be the best/only answer. If this is the only
way to do it, may I submit for consideration to the powers-that-be that this
is a blecherously hacky technique to have to use, to have a .ws run "a|b"
with the environment inherited from the .ws?
Totally off-side note: Is it safe to have a .bat file del itself?
Second totally off-side: If you gen tempnames like that, watch your back.
It's really unlikely, but possible, that two people will GetTempName, end up
with the same name, and one will create the file before the other does.
Either the second create will fail, or there will be two processes using the
same temp file. (I tend to put these in a loop to make sure I was able to
create a file with the suggested name.)
Thanks,
--
* Helen *
> Set WSHShell = WScript.CreateObject("WScript.Shell")
Yes, as long as the DEL statement does NOT end in a newline (LF/CR).
This is an old DOS batch trick. Notice the DEL line in the script uses
a Write, rather than a WriteLine.
> Second totally off-side: If you gen tempnames like that, watch your back.
> It's really unlikely, but possible, that two people will GetTempName, end up
> with the same name, and one will create the file before the other does.
> Either the second create will fail, or there will be two processes using the
> same temp file. (I tend to put these in a loop to make sure I was able to
> create a file with the suggested name.)
Hmmm. That comment suggests a multi-user system where all users are
addressing the same TEMP folder. Even under the assumption of parallel
scripting process (which can occur), it suggests two (or more) requests
to create a temp name occurring from both processes within the same
clock tick and that the GetTempName process is non modal (which I, in my
niavety, assumed to be modal). I wouldn't think that was very
unlikely. My assumption was that the GetTempName is probably the best
way to AVOID the kind of thing you are suggesting.
> Thanks,
> --
> * Helen *
>
> > Set WSHShell = WScript.CreateObject("WScript.Shell")
> > Set ofs = WScript.CreateObject("Scripting.FileSystemObject")
> > TempName = WshShell.Environment("PROCESS").Item("TEMP")
> > TempName = TempName & "\~" & ofs.GetTempName & ".bat"
> > Set otf = ofs.OpenTextFile(TempName, 2, True)
> > otf.WriteLine "set Var1=Whatever"
> > otf.Writeline "set Var2=Something else"
> > otf.Writeline "e:\legacy\prog.exe < c:\indata.txt"
> > otf.Write "del " & TempName
> > otf.Close
> > ReturnValue = WSHShell.Run ("%comspec% /c " & TempName, 0, True)
> >
> > Change the zero in the last line to one to reveal the DOS window of the
> > running program.
> >
> > This approach can be run from Wscript.exe and doesn't use the new
> > console support available only in the version 2.0 beta.
> >
> > Tom Lavedas
> > -----------
> > http://www.pressroom.com/~tglbatch/
--