Help redirecting output from spawned process

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Help redirecting output from spawned process

Bob Jarvis
I'm having a problem redirecting a spawned processes output to a file.
After much mucking about with _dup and _dup2 as per
CRTLibrary>>spawnForOutput:args: (and little success - never mind that
I've done this before in C without trouble) I decided to try using
CMD.EXE to run my command, using the /C switch to have it terminate
nicely after running the command, and using CMD's I/O redirection
(the '>' and '2>' operators on the command line) to do the I/O
redirection.  In all cases the temporary files are created properly,
but nothing is ever written to them.  The commands execute properly,
but the output from them is not captured.  A typical command line is

    cmd /C ci -u -m"Revised" -t-"Initial
version" "RcsSourceManager.cls" >C:\TEMP\1771.tmp 2>C:\TEMP\1772.tmp

(Pretend the above is all on one line).  This command is being launched
using
KernelLibrary>>createProcess:lpCommandLine:lpProcessAttributes:lpThreadA
ttributes:bInheritsHandles:dwCreationFlags:lpEnvironment:lpCurrentDirect
ory:lpStartupInfo:lpProcessInformation:, and as I say the process runs
fine and does its job properly.  But, dang it, the output is never
captured!  Running the same command in a command-line window without
the redirection shows the stuff being written to the screen as plain as
day, and if I run it from a command-line window with the redirection
included the output is redirected as expected.

At first I thought it was because (perhaps) when running a GUI app that
the standard files (stdin, stdout, and stderr) might not be defined,
which is why I switched to launching CMD, to be (reasonably) sure that
the standard I/O files would be present.  I even tried switching the /C
switch to /K when running CMD.EXE, hoping that would keep the window
around so I could perhaps see what was going on, but the window just
flashed up and disappeared no matter whether I used /C or /K.

AGGGGHHHHHHH!!!!!!!!!

<sigh>

Can anyone shed some light on this?  And/all help gratefully
appreciated.
--
Bob Jarvis
Compuware @ Timken


Sent via Deja.com http://www.deja.com/
Before you buy.


Reply | Threaded
Open this post in threaded view
|

Re: Help redirecting output from spawned process

Don Rylander
Bob, just off the top of my head, try it without the the redirection, but with
" & pause" appended to the end of your command line.  That should leave the
output on the screen and force the window to stay open until you feed it a
keystroke.  Good luck.

Don


Reply | Threaded
Open this post in threaded view
|

Re: Help redirecting output from spawned process

Bob Jarvis
In article <9092jt$dt88$[hidden email]>,
  "Don Rylander" <[hidden email]> wrote:
> Bob, just off the top of my head, try it without the the redirection,
but with
> " & pause" appended to the end of your command line.  That should
leave the
> output on the screen and force the window to stay open until you feed
it a
> keystroke.  Good luck.

Good thought, but it didn't work - the process terminated anyways.  I
even tried changed the /C flag to /K, but the window still slams shut.
I've even tried dropping in a 'self halt' before I close the thread and
process handles returned in the PROCESS_INFORMATION struct, but still
no joy.

HOWEVER - I have now gotten it to work with code borrowed and
bastardized from CRTLibrary>>spawnForOutput:args:.  By replacing
the '_dup/_dup2' code in CRTLibrary>>spawnForOutput:args with command-
line redirection it then works - but I still don't understand why the
code which uses KernelLibrary>>createProcess:... *doesn't* work.
Unfortunately the code borrowed from CRTLibrary doesn't let me control
how the window is shown, so I get this command-line window which
flashes up briefly, which is objectionable (to me - OK, I'm picky) so I
really *want* to get the CreateProcess stuff working right.

Still, progress is progress...  :-)
--
Bob Jarvis
Compuware @ Timken


Sent via Deja.com http://www.deja.com/
Before you buy.


Reply | Threaded
Open this post in threaded view
|

Re: Help redirecting output from spawned process

Ted Bracht-2
Hi Bob,

"Bob Jarvis" <[hidden email]> wrote in message
news:9097mf$vc0$[hidden email]...

>
> HOWEVER - I have now gotten it to work with code borrowed and
> bastardized from CRTLibrary>>spawnForOutput:args:.  By replacing
> the '_dup/_dup2' code in CRTLibrary>>spawnForOutput:args with command-
> line redirection it then works - but I still don't understand why the
> code which uses KernelLibrary>>createProcess:... *doesn't* work.
> Unfortunately the code borrowed from CRTLibrary doesn't let me control
> how the window is shown, so I get this command-line window which
> flashes up briefly, which is objectionable (to me - OK, I'm picky) so I
> really *want* to get the CreateProcess stuff working right.

As you might have seen, I've been struggling in this same arena (see my
threads Talking to Java and Talking to an external program a couple of weeks
ago), and I didn't get it to work. I put it aside because of time
constraints, but eventually I need to get it to work properly (I now just
output to a file and pick up the file from within Smalltalk).

Things that I tried and did not get to work:
ShellLibrary>>shellOpen:
ShellLibrary>>shellExecute: and the rest
These should return a handle that should be able to be interpreted by
StdioFileStream class>> fromHandle: handle
KernelLibrary>>winExec:uCmdShow:
KernelLibrary>>commandLine:toArgvW:

Therefore I'm VERY interested in your progress, could you for example
elaborate on your CRTLibrary>>spawnForOutput:args: solution?

Thanks in advance,

Ted


Reply | Threaded
Open this post in threaded view
|

Re: Help redirecting output from spawned process

Bob Jarvis
In article <90fqtv$vk7n$[hidden email]>,
  "Ted Bracht" <[hidden email]> wrote:
> Therefore I'm VERY interested in your progress, could you for example
> elaborate on your CRTLibrary>>spawnForOutput:args: solution?

Here's the code which I plagiaraized from
CRTLibrary>>spawnForOutput:args: which uses _spawnvp to fire off a
console app, redirecting its output (in this case stderr only) to a
file.  There are several methods included so you can see precisely what
happens:

executeCommand: aStringCommand inDirectory: aDirectoryString
waitForSeconds: anIntegerSeconds
        "Execute a command by spawning a new process and waiting until
it completes."

        | tmpName tmpFile out argv args cmdString argString retval |

        tmpName := File temporaryFilename.

        cmdString := 'cmd'.
        argString := '/C "', (self doubleQuotesIn: (self driveFrom:
aDirectoryString) , ' && cd "',
                                                aDirectoryString, '"
&& ', aStringCommand), '" 2>', tmpName.

        Transcript show: 'argString = ', argString; cr.

        "This is rather horrid, but we need a vector terminated by a
null pointer"
        argv := DWORDArray new: 2.
        args := ' ', argString.
        argv at: 1 put: args yourAddress.

        retval := CRTLibrary default _spawnvp: 0 "_P_WAIT" cmdname:
cmdString argv: argv.
        retval == -1
                ifTrue: [self error: 'Fail to spawn ', cmdString].

        tmpFile := FileStream read: tmpName.
        out := tmpFile contents.
        tmpFile close.
" File delete: tmpName."
        ^out

doubleQuotesIn: aString
        ^aString inject: '' into: [ :tot :each | each = $" ifTrue: [
tot, '""' ] ifFalse: [ tot, (String with: each) ]]

driveFrom: aDirectoryString
        (aDirectoryString at: 2) = $:
                ifTrue: [ ^aDirectoryString leftString: 2 ]
                ifFalse: [ ^'' ]

As you can see I'm only redirecting stderr here because that's the only
file I really care about.  I expect that redirection of stdout would
work as well.  For robustness the above code should check the COMSPEC
environment variable to figure out which command-line interpreter to
run, but for development purposes I've got it hardcoded as 'CMD'.

I looked through the C runtime source included with VC++ 6 today, but
that hasn't given me any great insights.  I tried including the
CREATE_NEW_CONSOLE flag into the dwCreationFlags argument to
CreateProcess, thinking that might get me somewhere, but still no joy.
The C runtime lib *does* do some funky playing around with the
cbReserved2 and lpReserved2 fields in the STARTUPINFO struct but I
don't *think* it's relevant.  I've also tried setting the hStdOutput
and hStdError handles, and adding STARTF_USESTDHANDLES to the dwFlags,
*and* making sure that the bInheritHandles param to CreateProcess is
set to 'true'.  But <sigh> still no joy...
--
Bob Jarvis
Compuware @ Timken


Sent via Deja.com http://www.deja.com/
Before you buy.


Reply | Threaded
Open this post in threaded view
|

Re: Help redirecting output from spawned process

Ted Bracht-2
Hi Bob,

I've been playing around a bit further, and the best I've come up with is to
capture the command in a batch file and use

KernelLibrary default winExec: 'c:\myBatch.bat' uCmdShow: 0

By using uCmdShow: 0 it actually suppresses the command window.

Hope this helps, I'm still not there yet either.

Ted


Reply | Threaded
Open this post in threaded view
|

Re: Help redirecting output from spawned process

Bob Jarvis
In article <90kvqd$1eugr$[hidden email]>,
  "Ted Bracht" <[hidden email]> wrote:
>
> I've been playing around a bit further, and the best I've come up
with is to
> capture the command in a batch file and use
>
> KernelLibrary default winExec: 'c:\myBatch.bat' uCmdShow: 0
>
> By using uCmdShow: 0 it actually suppresses the command window.

Thanks for the help.  Given the above and a bit more fiddling around I
think I've finally got something that I like.  What I did was define a
SHELLEXECUTEINFO class to map the Win32 structure of the same name in
Dolphin, and then added the ShellExecuteEx command to ShellLibrary.
This allows me to execute the batch file *and* get back a process
handle I can wait on using WaitForSingleObject.  I've got a couple of
packages that provide this functionality.  I can email them to you if
you want to take a look at them.
--
Bob Jarvis
Compuware @ Timken


Sent via Deja.com http://www.deja.com/
Before you buy.