Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

Win32::Process redirect CMD output to text file

by sdyates (Scribe)
on Jun 25, 2002 at 16:06 UTC ( #177124=perlquestion: print w/ replies, xml ) Need Help??
sdyates has asked for the wisdom of the Perl Monks concerning the following question:

Thanks to everyone who has provided direction to me as I embark on using Win32::Process. Migrating from system() to Win32::Process has been anything but easy. However, I have overcome one major obsticle, to encounter another.

When I launch a new process, I want to be able to take the contents of the ourput and direct it to my $dump file. However, i cannot figure out how to redirect this output. I do not want to redirect all cmd output, just what the command 'identify' generates.

I have seen many documents throughout the web, yet none have provided me the right way to go. Even the man ages left me scratching my head. Once again, I have included the code in case you may have questions on my code.


thanks again.
simon.
############################################################# # This script checks the validity of image files using # # Image Magick's Identify command. This script works with # # various file formats. Several variables can be changed to # # altering logging and analysis. # # # # Simon D. Yates 30may02. # # Simon D. Yates Version 2.00.0168 18jun02. # ############################################################# # Allow this for emailing on errors. Will also require the email metho +d # Email me at sdyates2001@yahoo.com for the method. # use LWP::UserAgent use File::Find; use Win32::Process; #>---------------[ Customisable variables ]----------------- my $SummaryHTML = ">c:\\sdy\\summary.html"; # Location of Summary.html. Report summary in html format. my $SummaryCSV = ">c:\\sdy\\summary.csv"; # Location of Summary.csv. Report summary in csv format. my $SummaryCSVread = "<c:\\sdy\\summary.csv"; # Location of dump.txt. Contains granular data on each image tested. my $dump = "c:\\sdy\\dump.txt"; # Location of error.txt. Contains a list of potentially corrupt images +. my $error = ">>c:\\sdy\\error.txt"; # Specify "yes" to allow good images to be copied to $CopyDestination my $CopyGoodImages = "yes"; # by-passes prompting sections when set to other than no my $AutoScript = "yes"; # Specify the root directory where the images will be analysed and cop +ied from my $CopySource = "j:\\ClientSupportFiles\\workbook"; # Specify the directory where the good images will be copied to my $CopyDestination= "c:\\sdy"; #>----------------------[ variables ]------------------------ my @Structure=('\#\#','Format','Geometry','Class','Type','Depth', 'Colors','Filesize','Compression','Tainted'); #>---------------------[ Main logic ]------------------------ # Generates time stamp for log files Date(); # prompts for Source directory. RetrieveValues(); # Analyse each image and dump raw data and log errors CheckImageArchieve(); # Create summary file of images processed GrepImageDetails(); print OUTPUT "\n"; # Creates HTML file from CSV file PrintHTML(); #>----------------[ Subroutine Section ] -------------------- sub RetrieveValues { if ($AutoScript eq "no") { print "\n\nSpecify the Directory path to image folder:\n"; $directory = (<STDIN>); chomp $directory; } } sub CheckImageArchieve { my $a = 0; if ($AutoScript = "yes") { $directory=$CopySource } opendir(DIR, $directory) or die "Cannot open directory $directory" +; find (\&RetrieveAll, $directory); system ("cls"); while ($DIR[$a]) { open (STDERR, "$error") or die "$!"; # verbose option is critical for creating summary file $file="$DIR[$a]"; if (-d $file) { system("echo ##: $DIR[$a](SUB DIRECTORY) >> $dump"); print "DIR: $file" . "\n" } elsif (-f $file) { system("echo ##: $DIR[$a] >> $dump"); print "$DIR[$a]\n"; $DIR[$a] =~ s/\\/\\\\/g; Win32::Process::Create($ProcessObj,"J:\\imagemagick\\win2k +\\ImageMagick\\identify.exe","identify -verbose $DIR[$a] >> $dump",0, +NORMAL_PRIORITY_CLASS,"."); $ProcessObj->Wait(INFINITE); $ProcessObj->GetExitCode( $ExitCode ); print "\nExit: $ExitCode\n"; if ($ExitCode ne "1") { print STDERR "##: $DIR[$a] likely corrupt!\n". "--------------------------------------------- +-----\n"; $img="bad"; } else { $img=(); } CopyGoodImage(); } $a=$a+1; close STDERR; } } sub GrepImageDetails { open (INFILE, "<$dump") or die "Cannot open $dump file"; open (OUTPUT, $SummaryCSV) or die "Cannot open Summary CSVfile"; print OUTPUT "\n$Date\n"; print OUTPUT "File,Format,Geometry,Class,Type,Depth,Colors,Filesiz +e,Compression,Tainted"; while (<INFILE>) { $SFS = $_; $z=0; foreach $Structure(@Structure) { if ($SFS =~ m/$Structure[$z]/) { if ($Structure[1] =~ m/Format/) { if ($SFS =~ m/\#\#/) { print OUTPUT "\n"; } } $SFS =~ s/$Structure[$z]: //; $SFS =~ s/ //g; $SFS =~ s/\r//g; chomp $SFS; if ($z ne 9) { print OUTPUT $SFS . ","; } else { print OUTPUT $SFS; } print $SFS . "\n"; } $z=$z+1; } } $z=$z+1; close INFILE; close OUTPUT; } sub Date { ($sec,$min,$hou,$day,$mon,$yer,$wek,$dy,$DST)=localtime(time); my $rlm=$mon+1; my $yer=$yer+1900; if ($rlm == 1) {$rlm = "Jan"} elsif ($rlm == 2) {$rlm = "Feb"} elsif ($rlm == 3) {$rlm = "Mar"} elsif ($rlm == 4) {$rlm = "Apr"} elsif ($rlm == 5) {$rlm = "May"} elsif ($rlm == 6) {$rlm = "Jun"} elsif ($rlm == 7) {$rlm = "Jul"} elsif ($rlm == 8) {$rlm = "Aug"} elsif ($rlm == 9) {$rlm = "Sep"} elsif ($rlm == 10) {$rlm = "Oct"} elsif ($rlm == 11) {$rlm = "Nov"} elsif ($rlm == 12) {$rlm = "Dec"}; $Date="$hou"."h"."$min:$sec $rlm-$day-$yer"; } sub RetrieveAll { $File::Find::dir =~ s/\//\\/g; $_ =~ s/\//\\/g; push (@DIR,$File::Find::dir."\\".$_); } sub SummaryHTML { print OUTPUTHTML "</tr></table></p></BODY></HTML>"; } sub PrintHTML { open (OUTPUTHTML, $SummaryHTML) or die "Cannot open Summary HTML f +ile"; open (SUMMARY, "$SummaryCSVread") or die "Cannot open $dump file"; print OUTPUTHTML "<HTML><HEAD> <META NAME='GENERATOR' Content='Zoom Image Server Library'> <TITLE></TITLE> </HEAD> <TABLE BORDER=0 width=1000 cellpadding=2 align=left bordercolo +r='#FF9933' body bgcolor=steelblue> <TR><TH><font face=arial size=2>File name</TH> <TH><font face=arial size=2>Format</TH> <TH><font face=arial size=2>Pixel size</TH> <TH><font face=arial size=2>Class</TH> <TH><font face=arial size=2>Depth</TH> <TH><font face=arial size=2>Colour Depth</TH> <TH><font face=arial size=2>Colours</TH> <TH><font face=arial size=2>File size</TH> <TH><font face=arial size=2>Compression</TH> <TH><font face=arial size=2>Tainted</TH></TR> <font face='Courier'><TR><TH>"; $directory=~ s/\\/\\\\/g; while (<SUMMARY>) { $line=$_; $line =~ s/,/\<\/td\>\n\<td width='100' height='20' font face= +arial size='1' bordercolor='#FFFFCC' bgcolor='#FFFFCC' align=left\>/g +; # replace with scalar representing the path if ($line =~ m/$directory/) { print OUTPUTHTML "<tr><td width='150' height='20' font fac +e=arial size=1 border='1' bordercolor='#FFFFCC' bgcolor='#FFFFCC' ali +gn='left'>$line</td></tr>"; print OUTPUTHTML "\n"; } } close SUMMARY; close OUTPUTHTML; } sub CopyGoodImage { if ($img eq "bad") { print "$file is potentially damaged.\nFile not coppied!\n\n"; $img=(); } else { print "$file is fine\n"; if ($CopyGoodImages eq "no") { print "File copy is turned off\n\n"; $img=(); } else { print "Copying $file ...\n"; system ("copy $file $CopyDestination\n"); } print "\n"; $img=(); } }

Edit kudra, 2002-06-25 Added readmore

Comment on Win32::Process redirect CMD output to text file
Download Code
Replies are listed 'Best First'.
Re: Win32::Process redirect CMD output to text file
by flounder99 (Friar) on Jun 25, 2002 at 16:48 UTC
    I think Win32::Process::Create creates a new process directly from the program you send it. It does not start a shell and then have the shell start the process. Redirecting is a function of the shell. You may have to start "cmd" or "command" (depending on your shell) and have it start identify.exe in your Win32::Process::Create call.

    --

    flounder

      Eitherway, I should be able to redirect the contents of the command from the screen to a file on disk. If I can do this using system, I am sure I can do it with Win32::Process, just cannot figure out how to do it. I cannot believe that Win32::Process would be lacking in that area. I am more convinces in my own ignorance that Win32's ignorance.

        Here, look at this
        use Win32::Process; Win32::Process::Create($ProcessObj, 'c:\winnt\system32\cmd.exe', "/c echo foo>foo.txt", 0, NORMAL_PRIORITY_CLASS,".")||warn "could not create process";
        instead of echo foo put in the program you want to run. Win32::Process is doing what you ask of it - it is creating a process running "identify.exe". "indentify.exe" does not know how to redirect. You have to run "cmd.exe" and have it start "identify.exe" and redirect the output to a file. system transparently starts a shell (cmd.exe) and hands it the parameters, the first of which is the program it should run. Most people from a windows background don't understand that a command prompt is actually a program called "cmd.exe" (or "command.com" on dos/win9x)

        Update:
        Note: the name of your shell is probably available in $ENV{COMSPEC}

        --

        flounder

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://177124]
Approved by particle
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (8)
As of 2015-07-30 17:58 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (273 votes), past polls