Solved

Running EXE files from within a Perl Script

Posted on 2007-11-27
25
2,889 Views
Last Modified: 2013-12-25
I have written a piece of bespoke booking software in Perl on the Xampp implementation of Apache and I've encountered a problem running .EXE files.

My software ties in to the popular (in the UK) Sage Accounting package.  The company (Sage) supplies a set of develoment tools to read and write data to and from the accounts database but they only supply these tools in VB6 and VB.NET format.  I have Visual Studio and so used the VB6 version of the tools to produce an .EXE file which basically pulls out the next valid invoice number from the Sage accounts database.  It will do more, I just haven't got that far yet!

My problem is this, when I try to call my .EXE using the SYSTEM command in PERL, the browser tries to call the code but basically never returns, i.e. the bar at the bottom of the browser very very slowly inches forward but nothing further happens.

My .EXE file should create a file when it runs but doesn't so I assume that the .EXE is just not executing.  If I call my .EXE file via RUN, it all works fine.  I've tried to open Notepad using SYSTEM but exactly the same thing happens.

My software also uses Easy Software's HTML2PDF software to generate PDF files, the same executable can be run directly as a Windows application or in PERL using the SYSTEM command and it has always worked fine so I'm assuming that there's some problem with the EXE file that VB6 is generating - any help would be greatly appreciated.
0
Comment
Question by:frasierphilips
  • 12
  • 6
  • 4
  • +3
25 Comments
 
LVL 19

Expert Comment

by:Kim Ryan
ID: 20362559
I would first try using the system call form a perl script that is run from the command line, not the browser. It should just be a simple one line script.

You could be facing problems with file permisions and groups, or restrictions on what commands you can run from a CGI (browser based) environment.
0
 
LVL 17

Expert Comment

by:mjcoyne
ID: 20363561
My .EXE file should create a file when it runs but doesn't...
...so I'm assuming that there's some problem with the EXE file that VB6 is generating ...

I'm confused -- too many executable files...

Are you saying that you're running a VB6 executable file from a Perl system call, and this VB6 executable creates another executable file as its output?  If so, how is this output executable being called?

Does the executable produced by the VB6 executable run correctly from the command line?

0
 

Author Comment

by:frasierphilips
ID: 20363801
The VB6 .EXE file is a small program that accesses the Sage accounting programs database (which is on the same computer) and retrieves the next available invoice number.

In order that my PERL based booking software can do its job (in this case to generate invoices) it needs to know what to start numbering the invoices from so it must run the .EXE file first but it can't because every time I try to call the EXE file my PERL script using the SYSTEM command, nothing happens other than the browser status bar slowly starting to build.

The .EXE runs perfectly if executed from the Command line.

The .EXE file retrieves the Invoice Number and saves it as a text file in the CGI-BIN directory for Perl to pick up, but this text file isn't being created when the EXE is called from within the PERL script so I'm assuming the EXE isn't executing at all.

I can't get Notepad.exe to run from my script either (I tried this as a simple test) however I use a program called HTML2PDF.EXE which creates PDF files and this runs perfectly from my PERL script using the SYSTEM command.
0
 
LVL 48

Expert Comment

by:Tintin
ID: 20363893
notepad.exe won't work as it will be trying to invoke that on the webserver, not on your PC.

What user are you running the vb6 exe from command line?
0
 

Author Comment

by:frasierphilips
ID: 20363929
Because I'm still developing the software, the XAMPP/APACHE is running on my local machine, not over a network, so it's all logged onto the same account.  What I don't understand, and none of the posts have addressed this, my script is running another EXE file, part of the HTML2PDF package, perfectly fine - this is a program we bought in, you install it on your Windows based system (it creates registry keys etc) then all I had to do to get it to run on the web server was copy the exe file HTMLDOC.EXE into the CGI-BIN folder and call it from the SYSTEM command - it worked perfectly first time, I didn't have to modify any Apache permissions, it just worked.  I've checked its permissions in Windows and they are no different to any other Windows file which is why I wonder if it's the structure of the EXE being created by VB6 that's the problem.
0
 
LVL 17

Expert Comment

by:mjcoyne
ID: 20365183
I'm not sure if this will help, but I have often found that problematic system calls to executables in Windows can be solved by using the "start" command and quoting.  For example:

system ("start \"$ENV{HOMEDRIVE}\\Program Files\\internet explorer\\iexplore\.exe\" \"$htmlfile\"");
system ("start wordpad.exe \"$txtfile\"");
system ("start \"$ENV{PROGRAMFILES}\\IrfanView\\i_view32\" $pic");
0
 

Author Comment

by:frasierphilips
ID: 20365223
Thanks, I tried that.  What I'm beginning to think is that because the VB6 EXE file is actually part of a Form object OnLoad event, when the EXE file is executed by Apache, the EXE tries to invoke a GUI which because of the scope of it's execution, it is unable to do so it just sits there waiting for the GUI to kick in.  Sage have suggested excuting the code as part of a VB.NET console object so I'm gonna give that a try.
0
 
LVL 39

Expert Comment

by:Adam314
ID: 20365926
Try changing your VB6 startup to be "sub main" instead of "form main".  I don't remember exactly where this option is, but I think it's in the project properties.
Then create a module (I think it's insert -> Module), create a sub main, and have all your code in there (or in other functions.., but no forms).
Then remove all forms from your application.
Recreate the exe file.
Try running this new exe file.

0
 
LVL 51

Expert Comment

by:ahoffmann
ID: 20368023
You're not calling the perl script (which contains your .exe call) from  the webserver (apache)? Are you?
That cannot work with .exe file which require/have a GUI like notepad.exe or ie.exe, obviously ...
0
 

Author Comment

by:frasierphilips
ID: 20368108
I tried Adam314's suggestion and it has stopped the browser 'stalling' so the code seems to be executing HOWEVER it's still not creating a file in the cgi-bin folder.  I wonder if this is a permission problem, i.e. the .EXE file isn't allow to save a file when executed by Apache.  As before, it does create the file if run from Windows.  The invoice number is 13635 - is it possible to send thiis as a return value from the EXE file?
0
 
LVL 39

Expert Comment

by:Adam314
ID: 20368517
Normally, a script will NOT have write access to your cgi-bin folder.  If you need to have your script write to a file, you should create a directory for that - it is not generally good security practices to allow a script to write to the cgi-bin folder.

If you don't want the EXE to create a file - you just need the number, you can have the VB6 app "print" the number.  This will go to the programs STDOUT.
Then, in perl, you can read that data using backticks instead of system.
eg:
If you had:
    system("myprogram.exe");
You would put:
    my $invoice_number = `myprogram.exe`;
    chomp($invoice_number);     #to remove the newline

0
 

Author Comment

by:frasierphilips
ID: 20369284
I changed the location for the file write to another folder (c:\xampp\xampp\htdocs\tmp) and it still didn't create a file.  

Also, I knew there was a reason why I steered clear of VB!  Is there any simple way of writing to STDOUT?  The simplest code I could find is:-

    Dim fso As New FileSystemObject
    fso.GetStandardStream(stdout).Write (Text)

The .EXE file can be created without error, but nothing turns up at the Perl end after the .EXE has supposedly executed.
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 39

Expert Comment

by:Adam314
ID: 20369660
Seems like a lot to write to stdout... but i guess vb is designed more for GUI type applications.  I don't use vb very often though, and don't know an easier way.

The user running apache will probably not be the same user that you use to log in.  If you want the program to be able to write to a file when running in apache, you have to give the apache user permission to do that.

When you run the vb exe program from the command line, does it create a file?  Do you get any output?
0
 

Author Comment

by:frasierphilips
ID: 20369756
To be honest, I don't even know if it is running, it doesn't hang anymore but also, I can't get anything to turn up at the Perl end and no file is created.  A few posts earlier, I mentioned a program we bought in called HTML2PDF.  It's a pretty solid program that turns HTML files into PDFs.  The reason I keep mentioning it is because it comes with a standard Windows installer and can be run from the Windows command line HOWEVER if you want to use it on a webserver (such as Apache running in Windows) you simply copy the executeable into the CGI-BIN folder and hey presto it just works.  I set it to create PDFs in the folder C:\XAMPP\XAMPP\HTDOCS\PDFS and it does so.  It didn't need any special permission changes or anything like and it's invoked via the PERL SYSTEM call.  

I'm starting to think that VB6 isn't up to this, I've got a copy of VB.NET coming tomorrow.
0
 
LVL 39

Expert Comment

by:Adam314
ID: 20370153
I don't think vb.net will make it any easier.  If you've never programmed in .net, there is a learning curve, as .net is very different from classic vb.

Try this:
copy your vb exe program to your cgi-bin folder
go to a command prompt
change to your cgi-bin folder (eg: cd \inetpub\wwwroot\cgi-bin)
Try to run your exe program: programname.exe

Do you get any output?
Is the file it is supposed to generate created?
Any error messages?

0
 

Author Comment

by:frasierphilips
ID: 20370190
No error messages, it worked perfectly.
0
 
LVL 39

Expert Comment

by:Adam314
ID: 20370391
By worked perfectly, it created the file and produced the desired output?

Is there anything in your logs that helps - either your apache log or the sage log?

Does your script (or any of it's libraries (eg: sage)) use any environement variables?
If so, you will have to have these set in your apache environment - they most likely will not be.

When checking the database, are there any permission required?  How does it determine this?
If it uses your login name, this will be different when running from within apache.

You might want to add some debugging output to your vb exe program.
For example, have it print a message every so often about what it is doing.
Then, when run from your webserver, you will get some output to help you figure out what is causing the problem.
0
 

Author Comment

by:frasierphilips
ID: 20372242
I think that's the big problem, I actually don't know what's hapeening with the VB script. - is it executing or not?  I'm now pretty proficient with Perl but on a need-to-know basis with VB.  As far as I can determine, and it's backed up by some of the other postings on here, I can't have anything in my VB that requires screen output to a Windows object such as a form because if I do, the EXE file it produces can't be run by Apache because it invokes the GUI.

This leads onto trying to invoke the Windows console to capture any output but apparently this is a very invloved process on VB6 whereas I'm lead to believe that VB.NET actually has a console object.

I think what I'll do first is see if VB6 has some way of beeping the PC speaker and add that to the start of the code, at least if the speaker beeps I'll know if the EXE is running.
0
 

Author Comment

by:frasierphilips
ID: 20372292
I added a beep to the VB code and recompiled it and lo and behold, a beep when you clicked the link to the Perl calling script.  So the EXE is running, it just isn't passing a value back or creating a file.
0
 
LVL 17

Expert Comment

by:mjcoyne
ID: 20372740
We really, really need to know the behavior of this VB6 program when run from the command line -- a full and complete answer, not just "it works perfectly"...

Is there a GUI invoked when it's executed from the command line?  If there is, there will be when Perl calls it, too, if there isn't, there won't be.

Is a file produced by the VB6 program when it's run from the command line?

Is there any pertinent information in your Apache error logs?  How about the Window's event logs (run eventvwr from the command line)?

Is there a reason you must use a VB script to perform this step in your program?  Can't Perl do it?
0
 

Author Comment

by:frasierphilips
ID: 20372775
There is no GUI - I have gone to great lengths to make sure there are no components in the VB6 script that would invoke the GUI and the code is run from a SUB MAIN not a FORM.

The file is produced when run from the command line - i.e. it works perfectly

There is no info in the Apache log.

I've got to use VB because Sage (which won't mean much to you if you aren't in the UK, but they are a VERY big deal in accounting software in this country, probably 90%+ of businesses that use computerised accounts use their software)  only supply the modules to integrate third party software with theirs in VB6 and VB.NET formats.

And to reiterate my last comment, when I added a BEEP command to the script, there is a beep when the Perl script link calling the EXE is clicked so the EXE is running, it simply isn't creating the file or passing back a return value.
0
 
LVL 17

Expert Comment

by:mjcoyne
ID: 20372926
Nothing in the Windows event logs, either?

What is the reurn code of the system command ($status = $?; after the system call)?

What if you explicitly re-direct output?  Something like:

system("VB6_command >stndout.txt  2>stnderr.txt");

What happens if you use the exec() command, rather than the system() command?

Call the DOS set command via a sytem call:

system("set >system_env.txt");

and compare it to the output of running the set command from the DOS command line.  are there any differences between the two outputs?
0
 

Author Comment

by:frasierphilips
ID: 20372949
Will try your suggestion, SYSTEM returns 0 after call
0
 
LVL 39

Accepted Solution

by:
Adam314 earned 500 total points
ID: 20373778
You need to add some additional output to your vb program to help figure out where the problem is.

Suppose this is your program.  Add the new lines:

sub main()
    Dim fso As New FileSystemObject     'NEW
    fso.GetStandardStream(stdout).Write ("Starting...")    'NEW
    'Stuff your program does to initialize
   
    fso.GetStandardStream(stdout).Write ("Step 1...")    'NEW
    'Your program does some more stuff
   
    fso.GetStandardStream(stdout).Write ("Step 2...")    'NEW
    'Your program does some more stuff
   
    fso.GetStandardStream(stdout).Write ("Step 3...")    'NEW
    'Your program does some more stuff
   
   
    fso.GetStandardStream(stdout).Write ("Step 4...")    'NEW
    'Your program prints it's number
    fso.GetStandardStream(stdout).Write (number)
end sub



Then call the perl script from your perl script run by apache.
0
 

Author Comment

by:frasierphilips
ID: 20376241
Problem solved - believe it or not (and I can't think why I didn't spot this) my home PC is running VISTA Ultimate - it was stopping the script from executing.  When I tried it on the XP machine at work, hey presto!  
0

Featured Post

Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

Join & Write a Comment

The ECB site provides FX rates for major currencies since its inception in 1999 in the form of an XML feed. The files have the following format (reducted for brevity) (CODE) There are three files available HERE (http://www.ecb.europa.eu/stats/exch…
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
Learn the basics of lists in Python. Lists, as their name suggests, are a means for ordering and storing values. : Lists are declared using brackets; for example: t = [1, 2, 3]: Lists may contain a mix of data types; for example: t = ['string', 1, T…
In this fifth video of the Xpdf series, we discuss and demonstrate the PDFdetach utility, which is able to list and, more importantly, extract attachments that are embedded in PDF files. It does this via a command line interface, making it suitable …

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now