SmugX has asked for the wisdom of the Perl Monks concerning the following question:
Hello, I have a strangish question that might be a Perl problem or not, depending on it's solution. :-)
I have a DOS app (running on Win2k) which reads in a text file. However, what I really want is for a Perl program to run "magically/silently" in the background and generate the CSV data to provide to the DOS app. So the DOS app would just think it was reading a text file, but really it was running Perl and capturing the output. (I can't change the DOS app's behaviour, by the way.)
I did wonder if there was a Windows app to give me this functionality, but I can't find anything.
Alternatively, does anyone think I could do something clever by monitoring/intercepting the file access from a continually-running Perl process, or does anyone have any other ideas as to how this strangeness might be accomplished?
Many thanks and excuse me if I'm making no sense at all,
Neil.
Re: Making a perl program look like a regular file on Win32?
by matija (Priest) on Mar 03, 2004 at 12:03 UTC
|
Well, under Unix you would do this with a named pipe, but I had no idea if named pipes even existed under Windows.
So I ran a google search, and I came up with description of activestate Win32::Pipe module.
Looks to me like it's just what you're looking for.
The way it would work is that you run the perl script, which will open a pipe with the name that is then passed to the DOS program just as if it were a normal file.
| [reply] |
Re: Making a perl program look like a regular file on Win32?
by Roger (Parson) on Mar 03, 2004 at 12:11 UTC
|
I did wonder if there was a Windows app to give me this functionality, but I can't find anything.
Yeah there is, it's called the device driver kit. :-)
http://www.microsoft.com/whdc/ddk/winddk.mspx
From what I read in your post, I have a feeling that you are not looking for a solution that simply preprocess the CSV and fire-off the dos app, but rather you are looking for something that hooks into the file open and file access. So that when your program, say, opens 'generate.pl' for read, it actually runs the perl script, and read from the text file instead. Kind of transparent to the DOS application.
So basically you want to create a device driver that hooks into the file I/O subsystem under Windows. When a process tries to open a file, it checks the extension of the file, if it matches 'pl', then it executes the perl script, generates the CSV file, and then open the CSV file instead.
So the answer is yes, it is possible. But a bit insane. :-)
Update: The Win32::Pipe module mentioned above by matija is certainly worth a try, before you diving deeper into Windows internals. But that's only half the solution, you will still need to hook into the Windows I/O subsystem somehow to trigger the execution of the Perl script.
| [reply] |
Re: Making a perl program look like a regular file on Win32?
by Koosemose (Pilgrim) on Mar 03, 2004 at 11:59 UTC
|
You could simply pipe the perl script to it (i.e. perl script.pl | someprog
Or for a more Perlish solution: in the script you could open a pipe to the program open HANDLE "|someprog.exe; and print to that filehandle. Though unless the program is in your PATH, you'll have to use the full path name to the program
Just Another Perl Alchemist
| [reply] [d/l] [select] |
Re: Making a perl program look like a regular file on Win32?
by inman (Curate) on Mar 03, 2004 at 12:19 UTC
|
I am assuming that your EXE is already compiled and doesn't support piped data (already mentioned as a good method). I am also assuming that the EXE works with the CSV from either a known location or a location passed on the command line. You can always run the EXE from a CMD file that executes your Perl App first before running your EXE. The Perl app simply writes the CSV file to a location that is known to the EXE.
You can even play around with the Windows shortcut that launches the app so that the icon looks like the original EXE's. The users will see the CMD window for the duration of the Perl scripts execution.
rem A command file that runs a Perl app before running a windows App.
perl camel.pl
start winldap.exe
| [reply] [d/l] |
|
Thanks for all your comments.
Roger, yes, your "insane" suggestion is along the lines that I was thinking. :-) However, I fear the Windows Driver Dev Kits may be a little beyond my Perl dev skills. :-( (I will go on the hunt for software that may achieve this, however.)
The pipe suggestions would normally be ideal, but don't work for my specific circumstance. Basically, the DOS app runs continually, but periodically reads the file which I want to intercept access to. (My fault for not detailing that in my problem description!)
You have all given me food-for-thought, however, and I will renew my searching and go read up on named pipes!
Many thanks, Neil
| [reply] |
|
I've had good luck with feeding DOS apps UNC names (\\system\file) in the past, if you can make the file being read a UNC filename then host it on a separate box.
This "separate box" being a Unix machine using Samba (or some other file sharing system). The "file" can then be a unix named pipe as mentioned in previous responses, or you can hack samba directly to run programs to generate I/O to fill this "file" as it's being served out.
Well, I mean as long as we're talking insane ideas....
| [reply] |
Here's a quarter, download a real OS . . . :)
by Fletch (Bishop) on Mar 03, 2004 at 12:00 UTC
|
On some flavour of *NIX you'd use a named pipe (man mknod). Possibly cygwin provides something similar for wintendo, but I'd be highly sceptical. The best solution's probably going to be to write a wrapper which runs your perl program to generate the CSV and then runs the DOS exe pointed at that tmp file.
| [reply] |
Re: Making a perl program look like a regular file on Win32?
by crabbdean (Pilgrim) on Mar 03, 2004 at 14:59 UTC
|
| [reply] |
Re: Making a perl program look like a regular file on Win32?
by vladdrak (Monk) on Mar 03, 2004 at 19:14 UTC
|
You can subscribe to Win32 ChangeNotify messages, which would let you know when a file changed for whatever reason. I'm not sure if this helps in your situation, but it is kinda cool. If you don't have Win32::ChangeNotify installed, you can get it via PPM if you run ActiveState ala "ppm install Win32-ChangeNotify" or from CPAN using "perl -MCPAN -e 'install Win32::ChangeNotify'". Here's some sample code:
use strict;
my $logfile = "D:\\ChangeNotify.txt";
my $path = "D:\\";
use Win32::ChangeNotify;
ChangeWatch();
sub ChangeWatch {
#$filter can contain any of the below seperated by a |
#
#ATTRIBUTES Any attribute change
#DIR_NAME Any directory name change
#FILE_NAME Any file name change
#LAST_WRITE Any change to a file's last write time
#SECURITY Any security descriptor change
#SIZE Any change in a file's size
my $filter = LAST_WRITE;
my ($path,$subtree);
my $notify = Win32::ChangeNotify->new($path,$subtree,$filter);
$notify->wait or warn "Something failed: $!\n";
Notify($path,$subtree);
$notify->reset;
ChangeWatch();
}
sub Notify {
my ($path,$subtree)=@_;
open(FILE,">>$logfile) or die "could not optn $logfile: $!";
print FILE scalar localtime . "Change Detected at $path $subtree\n";
close FILE;
}
-Vlad
| [reply] [d/l] |
|
|