469,315 Members | 1,802 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,315 developers. It's quick & easy.

Win32::Process ... target problem

39
Hallo everyone,

After playing around with 'fork' in order to try to get a one process to monitor another, I have changed my tack and switched to Win32::Process. Indeed, it looks like this function will be able to do what I require:

A: Start a windows application
B: While that application is running regularly monitor a log file
C: If the windows application falls over or locks up, then the monitor process will kill the job and close the script cleanly, supplying an error code as return.

However, I am having some issues with the syntax and find that although I can use Win32::Process::Create to open the program I require (in this test 'notepad'), I find that the target file (here: nptest.txt) will not open. I just get a blank text document.

Here is a sample of my code ...

my $ProcessObj;
Win32::Process::Create($ProcessObj,
"C:\\WINDOWS\\system32\\notepad.exe",
"C:\\Temp\\nptest.txt",
0,
NORMAL_PRIORITY_CLASS,
"C:\\Temp") or die ErrorReport();

I have tried all kinds of variations in the path but couldn't get it to open the target file. I find this bizarre as the application itself (notepad and other windows applications) opens fine ... but not the target.

It must be some simple thing that I have missed but I have checked back with examples from the web and I just can't see it. Maybe a second pair of eyes will see what I have missed?

Or maybe you can suggest an alternative command/syntax/process for getting one (repeating) process to monitor another (long) process?

I'd be very grateful for any tips or thoughts that you have.

Regards and thanks,
Alan Searle.

(NB: The double backslashes are necessary otherwise notepad won't open)
Jan 30 '07 #1
17 5985
KevinADC
4,059 Expert 2GB
try using wordpad for the test.
Jan 30 '07 #2
asearle
39
Hi Kevin,

> try using wordpad for the test.

Yes, I tried with wordpad but got the same result: Wordpad opened fine but displayed a blank document (i.e. wouldn't open the target file).

This must be a simple syntax and/or understanding problem on my part and I'd be so grateful if someone could maybe test this on their PC and tell me what they get.

Many thanks,
Alan Searle.

PS: Don't foget you need ...

use Win32::Process;
use Win32;
Jan 31 '07 #3
KevinADC
4,059 Expert 2GB
I think the problem here is that the third argument to the Create() method is the commad line arguments you would pass to the process, but there is no command line argument for notepad that enables you to open an existing file. That is why I suggested you try wordpad (Write.exe on my old Win98 test server). This works for me:

Expand|Select|Wrap|Line Numbers
  1. my $ProcessObj;
  2. Win32::Process::Create($ProcessObj,
  3. 'C:\\WINDOWS\\Write.exe',
  4. 'Write.exe temp.txt',
  5. 0,
  6. NORMAL_PRIORITY_CLASS,
  7. '.') or die $!;

that opens wordpad and the temp.txt file.
Jan 31 '07 #4
KevinADC
4,059 Expert 2GB
I stand corrected (by myself no less) this works as well:

Expand|Select|Wrap|Line Numbers
  1. my $ProcessObj;
  2. Win32::Process::Create($ProcessObj,
  3. 'C:\\WINDOWS\\notepad.exe',
  4. 'notepad temp.txt',
  5. 0,
  6. NORMAL_PRIORITY_CLASS,
  7. '.') or die $!;
so your problem might just be in getting all the paths correct.
Jan 31 '07 #5
KevinADC
4,059 Expert 2GB
try like this:

Expand|Select|Wrap|Line Numbers
  1. my $ProcessObj;
  2. Win32::Process::Create($ProcessObj,
  3. "C:\\WINDOWS\\system32\\notepad.exe",
  4. "notepad C:\\Temp\\nptest.txt",
  5. 0,
  6. NORMAL_PRIORITY_CLASS,
  7. "C:\\Temp") or die ErrorReport();
Jan 31 '07 #6
asearle
39
Yippppeeee! ... it was syntax.

Yes, that fixed the problem ...

> 'C:\\WINDOWS\\notepad.exe',
> 'notepad temp.txt'

I now know/realize that the name of the program (here notepad) must be included in both the path and in argument where the target file is declared.

Thanks for helping me sort out this problem.

Regards,
Alan.
Jan 31 '07 #7
asearle
39
My testing with Win32 has been moving on and I am happy that I can get my application started. Now I need to be able to detect when the windows application (in my tests, msaccess) has closed.

In my example you can see how I call up msaccess (that works) and then set up a WHILE loop to carry out repeated actions (e.g. read a log file) until the Win32 application closes.

The WHILE loop works OK and (repeatedly) prints out the text 'waiting ...' but, when I close msaccess, the WHILE loop fails to exit. As you can see I am relying on the condition '$ProcessObj.STILL_ACTIVE' (I have also tried '$procreturn.STILL_ACTIVE').

I have googled on the key words and it seems that 'STILL_ACTIVE' is a valid option for Win32 so there must be something wrong with my syntax.

Any tips here would be a great help.

Regards and thanks,
Alan Searle

Snippet of my code ...

[... other code ...]
my $ProcessObj;
$procreturn=Win32::Process::Create(
$ProcessObj,
"C:\\mypath\\MSACCESS.EXE",
"msaccess C:\\anotherpath\\mymdb.mdb",
0,
NORMAL_PRIORITY_CLASS,
".")|| die ErrorReport();

while ( $ProcessObj.STILL_ACTIVE ) {
# $action = &read_logfile();
print "waiting ...\n";
sleep(3);
}
Feb 1 '07 #8
asearle
39
On CPAN I found the following explanation of how to apply the 'STILL_ACTIVE' constant but I am not sure how to incorporate it (with 'GetExitCode' ?) into my processing.

> $ProcessObj->GetExitCode($exitcode)
> Retrieve the exitcode of the process. Will return STILL_ACTIVE if the
> process is still running. The STILL_ACTIVE constant is only exported by
> explicit request.

Maybe someone has an idea or an example?

Many thanks,
Alan Searle
Feb 1 '07 #9
KevinADC
4,059 Expert 2GB
On CPAN I found the following explanation of how to apply the 'STILL_ACTIVE' constant but I am not sure how to incorporate it (with 'GetExitCode' ?) into my processing.

> $ProcessObj->GetExitCode($exitcode)
> Retrieve the exitcode of the process. Will return STILL_ACTIVE if the
> process is still running. The STILL_ACTIVE constant is only exported by
> explicit request.

Maybe someone has an idea or an example?

Many thanks,
Alan Searle
maybe:

Expand|Select|Wrap|Line Numbers
  1. while($ProcessObj->GetExitCode($exitcode)  eq 'STILL_ACTIVE') {
Feb 1 '07 #10
asearle
39
Hi Kevin,

Yes, your suggestion seems logical and so I tried ...

while($ProcessObj->GetExitCode($exitcode) eq 'STILL_ACTIVE') { [...]
while($ProcessObj->GetExitCode($exitcode) eq STILL_ACTIVE) { [...]
while($ProcessObj->GetExitCode($exitcode) == STILL_ACTIVE) { [...]

... and found that with this the process immediately exits the loop and ends while my windows application remains/is still active.

I tried once again to see what values GetExitCode returns and so re-activated the loop and got the system to print out the PID and the ExitCode these remain the same (ExitCode: 1) even after the application is closed. So there is something that I am not picking up.

I have googled a lot (really a lot!) and found information on CPAN but they don't seem to explain how to detect the ending of the process.

Anyway, many thanks for your tip: It looks plausible/correct (a colleague also suggested something similar) and so I'm even more bemused as to why it doesn't work.

Thanks,
Alan.
Feb 2 '07 #11
KevinADC
4,059 Expert 2GB
Expand|Select|Wrap|Line Numbers
  1. use Win32::Process qw(STILL_ACTIVE);
  2.  
  3. if ($ProcessObj->GetExitCode($exitcode) eq 'STILL_ACTIVE') {
  4.    do something
  5. }
  6.  
Feb 2 '07 #12
asearle
39
Hi Kevin,

Thanks so much for your help/tips. But 'use Win32::Process qw(STILL_ACTIVE);' also didn't help :-/

I have reduced my code to the absolute minimum with the goal of getting the process to detect when wordpad closes.

With Version 'A', I get an endless loop and with 'B' (your suggestion) I find that the WHILE loop exits immediately. I have included debug prints of PID and exit code (which display with Version 'A').

Maybe, if you have a spare moment, you could try to run it to see what you get?

Thanks very much,
Alan Searle

My Code ...

use Win32::Process;
use Win32::Process qw(STILL_ACTIVE);
use Win32;
#
print "Starting\n";
sleep(1);
my ($ProcessObj, $exitcode);
Win32::Process::Create($ProcessObj, "C:\\Program\ Files\\Windows\ NT\\Accessories\\wordpad.exe",
"wordpad C:\\Temp\\temp.txt",
0,
NORMAL_PRIORITY_CLASS,
".") || die ErrorReport();
# Version A: endless loop ...
# $ProcessObj.STILL_ACTIVE
# Version B: exits loop immediately ...
# $ProcessObj->GetExitCode($exitcode) eq 'STILL_ACTIVE'
while ($ProcessObj->GetExitCode($exitcode) eq 'STILL_ACTIVE') {
# $action = &read_logfile();
print "Waiting ... \n";
# print "Process waiting ", $ProcessObj->wait(INFINITE), "\n";
print "Process started with PID ", $ProcessObj->GetProcessID(), "\n";
print "Process completed with exit code ", $ProcessObj->GetExitCode( $exitcode ), "\n";
sleep(3);
}
print "ending\n";
sleep(4);
Feb 2 '07 #13
KevinADC
4,059 Expert 2GB
well, according to the documentation you have to import the STILL_ACTIVE constant:

The following additional constants are exported by request only:

STILL_ACTIVE

Expand|Select|Wrap|Line Numbers
  1. use Win32::Process qw(STILL_ACTIVE);
  2.     use Win32;
  3.  
  4.     Win32::Process::Create($ProcessObj,
  5.                                 "C:\\winnt\\system32\\notepad.exe",
  6.                                 "notepad temp.txt",
  7.                                 0,
  8.                                 NORMAL_PRIORITY_CLASS,
  9.                                 ".")|| die ErrorReport();
  10.  
  11.     my $status = $ProcessObj->GetExitCode($exitcode);
  12.     if ($status eq 'STILL_ACTIVE') {
  13.        print "still running\n";
  14.     }
  15.  
Feb 2 '07 #14
asearle
39
Hi Kevin,

> well, according to the documentation you have to import the STILL_ACTIVE
> constant:
> use Win32::Process qw(STILL_ACTIVE);

Yes, I see you doing that. And have incorporated this.

And I see you testing for the exitcode ...

> my $status = $ProcessObj->GetExitCode($exitcode);
> if ($status eq 'STILL_ACTIVE') {

... and I have also done a debug print on the exit code thus ...

print "Process completed with exit code ", $ProcessObj->GetExitCode( $exitcode ), "\n";

... and incorporated this into my background loop. However, the exitcode is always '1' both while the application is open and after it is closed down. Is this just the exit code for the action of opening the external application? I was expecting it to change when I close down wordpad (or notepad). But it doesn't.

I haven't been working with perl for so long and I think maybe I have a hole in my understanding: If GetExitCode() is always returning the same value (during and after the running of the application), then comparing it to the constant STILL_ACTIVE will make no difference (will it?).

I am a bit out of my depth here but I really do need to get a looping process to monitor the progress of the windows application and here I seem to be just soooooo close to working it out.

Many thanks for your patience.

Regards,
Alan.
Feb 2 '07 #15
KevinADC
4,059 Expert 2GB
Hi Alan,

I don't know why the function is not returning the expected STILL_ACTIVE message. I have never used this mdule before either and I am not familiar with the Win32 modules in general. So I have to do what you are doing, read the documents and try some code. Try adding this line to your code also:

use Win32;


I see it's used in the example code for Win32::Process so maybe it has to be included as well.
Feb 2 '07 #16
asearle
39
In the end it was my silly, silly error: I was testing the exit code of the process checking the exit code ... rather than checking the exit code. Arrggghh!

Anyway it should have been like this ...

Expand|Select|Wrap|Line Numbers
  1.  
  2. $ProcessObj->GetExitCode( $exitcode );
  3. print "Process completed with exit code $exitcode\n";  
  4.  
Anyway, I hope that my questions also help others who need to do the same thing.

Cheers,
Alan.
Feb 6 '07 #17
KevinADC
4,059 Expert 2GB
ahh, thanks for the update :)
Feb 6 '07 #18

Post your reply

Sign in to post your reply or Sign up for a free account.

Similar topics

reply views Thread by Guy | last post: by
reply views Thread by Carlo Filippini | last post: by
1 post views Thread by RL | last post: by
1 post views Thread by rob | last post: by
2 posts views Thread by Paolo | last post: by
1 post views Thread by Java and Swing | last post: by
1 post views Thread by CARIGAR | last post: by
reply views Thread by suresh191 | last post: by
1 post views Thread by Geralt96 | last post: by
reply views Thread by harlem98 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.