473,387 Members | 3,750 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

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 6307
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

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

Similar topics

0
by: Guy | last post by:
Hi, I created a function, which seems to work, quite well, it tells me if a process is running in widows using the pid number (I'm aware that the pid number in widows is not called a pid and this...
0
by: Carlo Filippini | last post by:
Hi on a XP machine I start a ftp process with: $pid = open (CMD, "ftp -in -w:1024 -s:$file_cmd $server 2>&1 |") or die "Can't execute: $!"; In some occasions I want to kill the process, but I...
1
by: RL | last post by:
Hi all, I am new and am lost with Win32::Process stuff. I want on perl script to start a process, then another perl script to terminate the same process. I can start a process using......
1
by: rob | last post by:
I created some Perl scripts on Win32 platform, and now I want to support the same for Linux. What are the equivalents for: 1) use Win32::Process; 2) use Win32::Process::Info; 3)...
2
by: Paolo | last post by:
There is something I can't understand which is the following. I have a system command which runs a commandline to unzip a file: my $Out = system ( $rootPath."bin/bin/gunzip -dfc "....
1
by: Java and Swing | last post by:
i need to get information about the processes running on a windows pc (98, 2k, xp) i can get the pid's using, win32process.EnumProcesses()...and I can get a handle on a process using an id..such...
3
by: jbenezech | last post by:
Hi All, I have a perl script which starts a java process using Win32::Process. Here is the code to start the java proces: Win32::Process::Create($ProcessObj, ...
0
by: jbenezech | last post by:
Hi all , I have a perl/java app running under Win32. The application consists of a perl service (Win32::Daemon) and of java classes. The perl service calls every xx hours java classes to perform...
1
by: Tension | last post by:
Hi, I am trying to run a Tornado simulator with Perl. The command line in an ordinary Windows command window looks like this: "C:\Tornado\target\config\simpc\vxWorks.exe /r32000000" Which I...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.