On Tue, 29 Apr 2008, Shuttlesworth, James wrote:
> 
> I was/am also having this problem, but generally ignored having the
> window- I can say for my part I do normally use backticks for most
> things, but I use win32process when I want more control over the
> process, for instance I want it to run for a certain amount of time and
> then kill it. For instance a little snippet that shows a PowerPoint
> slide for 15 seconds
> 
>     Win32::Process::Create($goodfile,
>        "c:\\progra~1\\microsoft office\\powerpoint viewer\\PPTVIEW.EXE",
>        "PPTVIEW.EXE \"$goodfile\" /s",
>        0,
>        NORMAL_PRIORITY_CLASS,
>        ".") || die ErrorReport();
>     Win32::Sleep(15000);
>     {$goodfile->Kill(0)}

You can still do this with the system(1, ...) syntax too:

    my @arg = ('-le', '++$|; while () { print ++$_; sleep(1) }');
    my $pid = system(1, $^X, @arg);
    sleep(5);
    kill 9, $pid;

You should make sure to use the system(1, $prog, @arg) form instead of
the system(1, $cmdline) version because the latter may run your $cmdline
indirectly via the cmd.exe shell[1] and the $pid returned by system() will
then be the pid of the cmd.exe process and not of your actual program.
Killing the cmd.exe shell will not terminate the child process. With
ActivePerl 820 and later you can of course use

    kill -9, $pid;

to kill not only $pid, but also all of its child processes. This still
doesn't work right if your program is a GUI application (like the
PowerPoint viewer above), because it will run detached from the cmd.exe
which can finish immediately after launching the GUI.

Oh, one thing I should mention about system(1, ...): Perl is keeping
the list of processes started this way in a table that is also used
to keep track of pseudo-threads created by the fork() emulation.  This
table is limited to something like 64 entries, so make sure you call
either waitpid() or kill() on the pids if you plan to create lots of
child processes over time.  The purpose of this table is that wait()
will now which child processes belong to the current Perl instance.
It also means you cannot have more than 64 child-processes running at
the same time. If you need more, then you have to use Win32::Process.

Cheers,
-Jan

[1] The decision to run a $commandline via cmd.exe is made at least
partially based on the existence of shell metacharacters (at least
'>', '<', '|' and '%', and possibly others) in the commandline.

The other criteria is that if $commandline fails to start without the
shell, then it will be retried via the shell just in case you are trying
to run one of the builtin shell commands ("echo", "dir", etc).


_______________________________________________
Perl-Win32-Users mailing list
[email protected]
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs

Reply via email to