Question about Win32::Process

R

readercn

Hi,dear all

I am quite new on Perl. Actually I am c++ programmer. So I have some
basic questions about perl,I need your help to find the right direction
:)

My task is to invoke a win32 application through web. This application
is dialog based.It reads some options from a txt file and then loads
data from data base using ADO. Finally the output will be an image.

The enviorment is Win NT+Apache+PHP+Perl. So can I do my task using
perl ?

I have tried to use Win32::Create() to invoke the application,but
nothing happened. I can invoke cmd.exe or calc.exe(although I can only
see it running in Task Manager).

I am in the mess about what perl can do and how to make remote call
running. Can anyone give me an example on how to do it ?

Thanks in advance
 
A

A. Sinan Unur

(e-mail address removed) wrote in @j33g2000cwa.googlegroups.com:

I am quite new on Perl. Actually I am c++ programmer. So I have some
basic questions about perl,I need your help to find the right
direction :)

My task is to invoke a win32 application through web.

ITYM that you have a CGI script that parses some form information, and
then spawns the win32 application.
This application is dialog based. It reads some options from a txt
file and then loads data from data base using ADO.

Please decide: Is the application dialog based (requiring a user or a
program emulating a user to enter information in a dialog when it runs
on the web server), or does it read options from a text file?
Finally the output will be an image.

*If* the win32 application really does read all the necessary
information from a text file and you can pass meaningful options to it
on the command line, this would require only a trivial call to system

In your CGI script:

* set up the options in a text file

* system(qw(/path/to/myapp.exe
--options=/path/to/options.txt
--output=/path/to/output.png));

* Then, your CGI script can redirect to http://myhost/output/output.png
The enviorment is Win NT+Apache+PHP+Perl. So can I do my task using
perl ?

Of course.
I have tried to use Win32::Create() to invoke the application,but
nothing happened. I can invoke cmd.exe or calc.exe(although I can only
see it running in Task Manager).

That is no different than if you had used the Win32 API call in C.
I am in the mess about what perl can do and how to make remote call
running. Can anyone give me an example on how to do it ?

Not with the limited information you have provided.

Please do read the posting guidelines for this group.

Sinan
 
H

Hao

Thanks a lot for your fast reply , Sinan :)
ITYM that you have a CGI script that parses some form information, and
then spawns the win32 application.
Yes,that's just what I mean.
Please decide: Is the application dialog based (requiring a user or a
program emulating a user to enter information in a dialog when it runs
on the web server), or does it read options from a text file?
It should read options from a text file,but the application itself is
dialog based. So maybe my question is whether 'system' can invoke
dialog based application like 'calc' or not ? I tried it several times,
I can see 'calc' running in task manager,but I can not see the
interface.

Please do read the posting guidelines for this group.
I can not access the link :(
http://mail.augustmail.com/~tadmc/clpmisc/clpmisc_guidelines.html
 
A

A. Sinan Unur

Thanks a lot for your fast reply , Sinan :)

Yes,that's just what I mean.

It should read options from a text file,but the application itself is
dialog based. So maybe my question is whether 'system' can invoke
dialog based application like 'calc' or not ? I tried it several
times, I can see 'calc' running in task manager,but I can not see the
interface.

Of course you can't. Where do you expect to see calc?

Is this code of yours top secret or something? If you expect
someone to provide useful feedback on your code, you ought to
show the code. It is only common sense.

Don't expect anyone to write your code for you.

You want a CGI script to invoke a program on the web server.
Said program can only be operated via its GUI. Then, you need
the CGI script to emulate pushing buttons, clicking menu items
etc.

http://search.cpan.org/~ctrondlp/Win32-GuiTest-1.50.3-ad/

might help.

I am sure it is a temporary problem.

Of course, a simple search of the archive of this group would
have yielded the required information:

http://groups.google.com/group/comp...roup=comp.lang.perl.misc&q=posting+guidelines

Sinan
 
H

Hao

Of course you can't. Where do you expect to see calc?
As you said, if there is no difference between Win32::Create() and
Win32 API call,then I can not see calc in both situations. But I can
see it when I create it using Win32 API.

CreateProcess( NULL, // No module name (use command line).
TEXT("calc"), // Command line.
NULL, // Process handle not inheritable.
NULL, // Thread handle not inheritable.
FALSE, // Set handle inheritance to FALSE.
0, // No creation flags.
NULL, // Use parent's environment block.
NULL, // Use parent's starting directory.
&si, // Pointer to STARTUPINFO structure.
&pi ) // Pointer to PROCESS_INFORMATION structure.
)
Is this code of yours top secret or something? If you expect
someone to provide useful feedback on your code, you ought to
show the code. It is only common sense.

Don't expect anyone to write your code for you.
It's not any secret,it's just very simple,what I wrote is

use Win32::process;
sub ErrorReport{
print Win32::FormatMessage( Win32::GetLastError() );
}

Win32::process::Create($ProcessObj,
"c:\\windows\\system32\\calc.exe",
"calc",
0,
NORMAL_PRIORITY_CLASS,
".")|| die ErrorReport();
which can be found in any perl textbook.
Of course, a simple search of the archive of this group would
have yielded the required information:

http://groups.google.com/group/comp...roup=comp.lang.perl.misc&q=posting+guidelines
I read the guideline, it's good and helpful. I will try to follow it :)

And I don't expect anyone write the code for me , I just want to find
the right direction before I dive into the technical details ~~
 
A

A. Sinan Unur

It's not any secret,it's just very simple,what I wrote is

use Win32::process;
sub ErrorReport{
print Win32::FormatMessage( Win32::GetLastError() );
}

Win32::process::Create($ProcessObj,
"c:\\windows\\system32\\calc.exe",
"calc",
0,
NORMAL_PRIORITY_CLASS,
".")|| die ErrorReport();
which can be found in any perl textbook.

I am not sure if you are doing this on purpose, but this is getting very
annoying:

D:\Home\asu1\UseNet\clpmisc> calc.pl
Global symbol "$ProcessObj" requires explicit package name at D:\Home
\asu1\UseNet\clpmisc\calc.pl line 10.
I read the guideline, it's good and helpful. I will try to follow it
:)

Well, then, please post code others can compile and run simply by
copying and pasting.
And I don't expect anyone write the code for me

Then how come you are not posting code that actually compiles?

Now, if I run

#!/usr/bin/perl

use strict;
use warnings;

use Win32;
use Win32::process;

sub ErrorReport {
Win32::FormatMessage( Win32::GetLastError() );
}

my $process;

Win32::process::Create($process,
'c:/windows/system32/calc.exe',
"calc", 0, NORMAL_PRIORITY_CLASS, '.')
|| die ErrorReport();

__END__

On my laptop, calc.exe starts and remains visible after the script
completes.

On the other hand, you were talking about invoking calc on the web
server via a CGI script which you invoke from a client computer. You
just ain't gonna see calc.exe on the client in that case.

In any case, why is system in combination with start not good enough for
you?

system qw(start c:/windows/system32/calc.exe);

Then you can use facilities provided by

http://search.cpan.org/~ctrondlp/Win32-GuiTest-1.50.3-ad/

to interact with the GUI.

Sinan
 
H

Hao

Well, then, please post code others can compile and run simply by
copying and pasting.
Well,I just didn't post the first line of my code :
'#!c:/perl/bin/perl'
I think it is different from one to another. It's up to where you put
perl.exe.
In any case, why is system in combination with start not good enough for
you?

system qw(start c:/windows/system32/calc.exe);
I tried to use 'system',but calc was not visible,that's why I turned to
Win32::process::Create.

Then I copy your code and change it to

#!c:/perl/bin/perl
use strict;
use warnings;
use Win32;
use Win32::process;

sub ErrorReport {
Win32::FormatMessage( Win32::GetLastError() );
}
my $process;
Win32::process::Create($process,
'c:/windows/system32/calc.exe',
"calc", 0, NORMAL_PRIORITY_CLASS, '.')
|| die ErrorReport();

Now calc is running but still invisible.Is there any configuration I
missed ?

Thanks a lot !
 
H

Hao

To Sinan

I know maybe my question is kind of simple and stupid,but why you can
see the interface of calc while I can not ?

Googled a lot ,but still no idea :(

A. Sinan Unur 写é“:
 
L

l v

Hao said:
To Sinan

I know maybe my question is kind of simple and stupid,but why you can
see the interface of calc while I can not ?

Googled a lot ,but still no idea :(

Since the Perl script is running on the web server, the web service
needs to be allowed to interact with the desktop. I do not know what
security issues this will cause. Do this via the service control panel
for your web service on the log on tab. I think you will need to
restart the service.

Len
 
A

A. Sinan Unur

@z34g2000cwc.googlegroups.com:

[ Please do not top-post ]
A. Sinan Unur 写é“:



I know maybe my question is kind of simple and stupid,but why you can
see the interface of calc while I can not ?

Are you running this script from the command line?

Sinan
 
H

Hao

Are you running this script from the command line?

No,I already set up the enviorment and I can run the simple
'hellowrold' script:

#!c:/perl/bin/perl
print "Content-type: text/html\n\n";
print "<H1>Hello World</H1>\n";

By the way , the OS on my laptop actually is WinXP, maybe NT would be
better ?
 
A

A. Sinan Unur

By *this script* I had meant the script spawning calc.exe.
No,I already set up the enviorment and I can run the simple
'hellowrold' script:

#!c:/perl/bin/perl
print "Content-type: text/html\n\n";
print "<H1>Hello World</H1>\n";

You will see that if you run

#!c:/perl/bin/perl
use strict;
use warnings;

use Win32;
use Win32::process;

sub ErrorReport { Win32::FormatMessage( Win32::GetLastError() ); }

my $process;
Win32::process::Create($process,
'c:/windows/system32/calc.exe',
"calc", 0, NORMAL_PRIORITY_CLASS, '.')
|| die ErrorReport();

__END__

from the command line, calc.exe will be visible.

However, see the reply by "l v" <[email protected]> who correctly
diagnosed the issue for why calc.exe is not visible when the script is
invoked as CGI through a web server that is running as a service.

You might be able to set permissions so that calc.exe appears on a
user's desktop, and the CGI script might be able to interact with it.
However, that is not a Perl question.

Or, you might be able to get you want by not running the web server as a
service.
By the way , the OS on my laptop actually is WinXP, maybe NT would be
better ?

No.

I, however, have to question why you want this script to run as CGI.
That is, why would you want people from all over the world to be able to
pop-up this GUI application on your laptop.

I strongly suspect there is a disconnect in your thinking somewhere and
that is why you insist on trying to accomplish whatever it is you want
to accomplish by running CGI scripts.

Sinan
 
H

Hao

I, however, have to question why you want this script to run as CGI.
That is, why would you want people from all over the world to be able to
pop-up this GUI application on your laptop.

I am just using my laptop to develop a 'web version' of the GUI
application. So our clients can input some options in a form,send it to
the server,and invoke the application to return output. If all these
been done,the real server will be set up instead of my laptop.
I strongly suspect there is a disconnect in your thinking somewhere and
that is why you insist on trying to accomplish whatever it is you want
to accomplish by running CGI scripts.

CGI is the interface between the server and applications,right ?And I
don't see any other way to do it.
 
M

Michael Greb

It is nice that you provided some context in your reply but you also
need to cite who wrote the quoted text.
I am just using my laptop to develop a 'web version' of the GUI
application. So our clients can input some options in a form,send it to
the server,and invoke the application to return output. If all these
been done,the real server will be set up instead of my laptop.

What computer the webserver runs on doesn't really matter, your laptop
for development or the "real server" in production use.
CGI is the interface between the server and applications,right ?And I
don't see any other way to do it.

What happens when two people twy to access this web page at the same
time? Like the person you were replying to (though I don't know who
they are as you didn't specify) I think that you haven't fully thought
this design through. What does this GUI application do that it is so
important for the web page? Can't you accomplish this whithout using
that application in a way it wasn't designed to be used?
 
H

Hao

I, however, have to question why you want this script to run as CGI.
That is, why would you want people from all over the world to be able to
pop-up this GUI application on your laptop.

I am just using my laptop to develop a 'web version' of the GUI
application. So our clients can input some options in a form,send it to

the server,and invoke the application to return output. If all these
been done,the real server will be set up instead of my laptop.
I strongly suspect there is a disconnect in your thinking somewhere and
that is why you insist on trying to accomplish whatever it is you want
to accomplish by running CGI scripts.

CGI is the interface between the server and applications,right ?And I
don't see any other way to do it.

I think my probem is about CGI, not Perl. Stupid question in wrong
place ......

Anyway,thanks for your time and patience !
 
A

A. Sinan Unur

I am just using my laptop to develop a 'web version' of the GUI
application. So our clients can input some options in a form,send it
to the server,and invoke the application to return output. If all
these been done,the real server will be set up instead of my laptop.
OK.


CGI is the interface between the server and applications,right ?And I
don't see any other way to do it.

It wasn't clear to me if you were developing this application for your
own use (and suffering from the sadly all too common "Perl is CGI"
syndrome). Apparently, you are not.

I would recommend the following:

1. At first, forget about CGI. Write a script that interacts with the
GUI (say, using Win32::GuiTest).

2. Once you get that working, install Apache and run it as a standard
user program rather than a service. See if you can get the script to
work via CGI. (Note that, in this case Apache will be running with the
user's privildges).

3. Then move on to figuring out what is needed to have service perform
the same task.

For (2) and (3), note that if a whole bunch of users hit the script at
the same time, there will be many instances of the Win32 GUI application
running, and that will adversely affect resources and performance.

There is a potential problem here. If, like calculator, the Win32 GUI
application you are running does not set the window title to something
distinctive, then some instances of the CGI script may trample on
instances of the GUI app spawned my other instances of the CGI script.
In that case, you are going to need a Win32 handle for each GUI app
window you create. Or, you can serialize accesses to the script (see
http://www.stonehenge.com/merlyn/WebTechniques/col54.html).

For (1), the following script, when run from the command line, should
give you an idea as to how to proceed.

#!/usr/bin/perl

# run this from the command line

use strict;
use warnings;

use Carp;

use Win32;
use Win32::process;
use Win32::GuiTest qw(
FindWindowLike
GetWindowText
SetForegroundWindow
SendKeys
);

use Win32::Clipboard;

my $program = q{c:/windows/system32/calc.exe};

my $process;

unless ( Win32::process::Create($process, $program,
"calc", 0, NORMAL_PRIORITY_CLASS, '.') ) {
croak ErrorReport();
}

# Give the process some time to full start
sleep 1;

my ($calc_window) = FindWindowLike 0, '^Calculator';

SetForegroundWindow $calc_window;
SendKeys '1{+}3=^C';

print '1 + 3 = ', Win32::Clipboard::GetText, "\n";

sub ErrorReport { Win32::FormatMessage( Win32::GetLastError() ) }

__END__
 
H

Hao

Michael Greb 写é“:
It is nice that you provided some context in your reply but you also
need to cite who wrote the quoted text.


What computer the webserver runs on doesn't really matter, your laptop
for development or the "real server" in production use.


What happens when two people twy to access this web page at the same
time? Like the person you were replying to (though I don't know who
they are as you didn't specify) I think that you haven't fully thought
this design through. What does this GUI application do that it is so
important for the web page? Can't you accomplish this whithout using
that application in a way it wasn't designed to be used?
Well, here is the scenario:
Forms on web page-->cgi script on server-->invoke this GUI
application-->reture an image to the webpage.
 
H

Hao

A. Sinan Unur 写é“:
It wasn't clear to me if you were developing this application for your
own use (and suffering from the sadly all too common "Perl is CGI"
syndrome). Apparently, you are not.

I would recommend the following:

1. At first, forget about CGI. Write a script that interacts with the
GUI (say, using Win32::GuiTest).

Yes, I already did this. Nice example !
2. Once you get that working, install Apache and run it as a standard
user program rather than a service. See if you can get the script to
work via CGI. (Note that, in this case Apache will be running with the
user's privildges).

Still looking Apache documents and googling on web. I am also a newbie
on Apache :(
However, I can not find the thread with the reply by "l v",could you
please give me the complete link ?
3. Then move on to figuring out what is needed to have service perform
the same task.

For (2) and (3), note that if a whole bunch of users hit the script at
the same time, there will be many instances of the Win32 GUI application
running, and that will adversely affect resources and performance.

Because this application is just for internal use,so we will alow only
one user at the same time.
There is a potential problem here. If, like calculator, the Win32 GUI
application you are running does not set the window title to something
distinctive, then some instances of the CGI script may trample on
instances of the GUI app spawned my other instances of the CGI script.
In that case, you are going to need a Win32 handle for each GUI app
window you create. Or, you can serialize accesses to the script (see
http://www.stonehenge.com/merlyn/WebTechniques/col54.html).

For (1), the following script, when run from the command line, should
give you an idea as to how to proceed.

#!/usr/bin/perl

# run this from the command line

use strict;
use warnings;

use Carp;

use Win32;
use Win32::process;
use Win32::GuiTest qw(
FindWindowLike
GetWindowText
SetForegroundWindow
SendKeys
);

use Win32::Clipboard;

my $program = q{c:/windows/system32/calc.exe};

my $process;

unless ( Win32::process::Create($process, $program,
"calc", 0, NORMAL_PRIORITY_CLASS, '.') ) {
croak ErrorReport();
}

# Give the process some time to full start
sleep 1;

my ($calc_window) = FindWindowLike 0, '^Calculator';

SetForegroundWindow $calc_window;
SendKeys '1{+}3=^C';

print '1 + 3 = ', Win32::Clipboard::GetText, "\n";

sub ErrorReport { Win32::FormatMessage( Win32::GetLastError() ) }

__END__

Thanks for your example, it gives me a clear idea.
 
H

Hao

l v 写é“:
Since the Perl script is running on the web server, the web service
needs to be allowed to interact with the desktop. I do not know what
security issues this will cause. Do this via the service control panel
for your web service on the log on tab. I think you will need to
restart the service.
Yes, I checked it and do what you suggested,but no help :(
Any other idea ?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top