The following only applies to Windows:
The following JScript program launches Perl in a hidden window, so it's almost like wperl.exe except your perl script will have access to stdout. The user will not be able to see what's printed to stdout or communicate with the script through stdin, because there will be no GUI window. None visible on the task bar or anywhere. But stdout does seem to work, because when I try to print character 0x07 to stdout from the perl script, which produces a bell sound, I can hear the sound. So, it prints to stdout just fine. But there's no other feedback or interaction with the script. And if your perl script has an infinite loop or it waits for STDIN, then the only way to stop the program is by killing it through Task Manager.
Now, here is the JScript program. This needs a little editing as you'll see. You have to edit the command line. On my computer, I have Windows XP running TinyPerl 5.8, and it's installed in C:\BIN\PERL and the test perl script I'm running is located in C:\DESKTOP. This test.pl file follows next.
CMD = "C:\\BIN\\PERL\\TINYPERL.EXE -I C:\BIN\PERL\LIB C:\\DESKTOP\\tes
+t.pl";
try
{
WshShell = new ActiveXObject("WScript.Shell");
WshShell.Run(CMD, 0);
}
catch (e)
{
WScript.Echo("Error: Couldn't start Perl script.");
}
The contents of the test.pl file:
#!/usr/bin/perl
use strict;
use warnings;
$| = 1;
print "\x07";
Here's a little more complex test.pl file, which displays certain info dialogs to show that it's running. It also produces some beeps to mark when the perl script exits:
#!/usr/bin/perl
use strict;
use warnings;
$| = 1;
AlertBox("Hello World!");
my $BUTTON = WinDialog("Do you want to exit now?", "My Little Perl Pro
+gram", 32 + 4, 0);
if ($BUTTON == 6) { Info("You pressed YES."); EXIT(2); }
if ($BUTTON == 7) { Info("You pressed NO."); }
my ($W, $H, $D) = GetScreenResolution();
Info("Your screen resolution is $W x $H x $D\n\nGood bye now!");
EXIT(1);
####################################################################
# Displays an information dialog box
# Usage: Info(STRINGs...)
sub Info { WinDialog(join("\n", @_), "Info", 64, 0); }
####################################################################
# This function returns the resolution of the primary
# display monitor. This function works on Windows ONLY.
#
# Usage: (Width, Height, ColorDepth) = GetScreenResolution()
sub GetScreenResolution
{
if ($^O =~ m/MSWIN/i)
{
my $JSCODE = "var MSIE = WScript.CreateObject('InternetExplorer.Ap
+plication');\r\nMSIE.Visible = 0;\r\nMSIE.Navigate('about:blank');\r\
+nMSIE.RegisterAsDropTarget = 0;\r\nMSIE.ToolBar = 0;\r\nMSIE.StatusBa
+r = 0;\r\nMSIE.FullScreen = 0;\r\nWScript.Sleep(50);\r\nMSIE.Document
+.open();\r\nMSIE.Document.write(\"\\x3CSCRIPT> document.write([screen
+.width,screen.height,screen.colorDepth].join(',')); \\x3C/SCRIPT></BO
+DY></HTML>\");\r\nMSIE.Document.close();\r\nWScript.Sleep(50);\r\nWSc
+ript.StdOut.WriteLine(MSIE.Document.body.innerHTML);\r\nMSIE.Quit();\
+r\n";
my $TEMPFILE = "C:\\TEMP\\SCRNRES0.JS";
mkdir "C:\\TEMP";
CreateFile($TEMPFILE, $JSCODE);
my $RES = `CSCRIPT.EXE /NOLOGO $TEMPFILE`;
return split(/,/, $RES);
}
return (0) x 3;
}
####################################################################
# This function writes some JScript code into a file and executes
# it using WSCRIPT.EXE. The function will return zero if the JScript
# code could not be run. All Windows versions starting with
# Windows 98 can run JScript by default.
# JScript is similar to JavaScript.
#
# Usage: INTEGER = RunJS(JSCODE)
sub RunJS
{
no warnings;
$^O =~ m/MSWIN/i && defined $_[0] && length($_[0]) or return 0;
mkdir "C:\\TEMP";
my $TEMPFILE = "C:\\TEMP\\JSTMP001.JS";
my $WSCRIPT = "C:\\WINDOWS\\SYSTEM32\\WSCRIPT.EXE";
-f $WSCRIPT or return 0;
local *FILE;
open(FILE, ">$TEMPFILE") or return 0;
binmode FILE;
print FILE $_[0];
close FILE;
-f $TEMPFILE && -s $TEMPFILE == length($_[0]) or return 0;
my $E = system("$WSCRIPT //NOLOGO $TEMPFILE");
unlink $TEMPFILE;
return $E + 1;
}
########################################################
# This function will pop up a tiny text box with a single
# "OK" button to click. Above it will be a custom text.
# The window size will grow depending on how much text is displayed.
# The title bar of the popup box will say "Windows Script Host."
# The function will not return control until the "OK" button
# is clicked. Returns 1 on success or 0 on error.
#
# Usage: INTEGER = AlertBox(STRING)
sub AlertBox
{
$^O =~ m/MSWIN/i or return 9;
my $S = '';
foreach (@_)
{
defined $_ && length($_) > 1 or next;
$S .= $_;
}
# Escape special chars
$S =~ s/([\\'\x00-\x1F\x7F-\xFF]{1})/"\\x" . sprintf('%.2x', ord($1)
+)/ge;
return RunJS("WScript.Echo('$S');WScript.Quit(1);") ? 1 : 0;
}
########################################################
# This function will pop up a dialog box in Windows with
# custom title and theme and buttons.
#
# The 1st argument should be the main text to be displayed
# in the dialog. The 2nd argument is the custom title bar.
# The 3rd argument should be an integer that determines the
# style and theme of the custom dialog.
# 0 = simple text box with a single "OK" button
# 1 = OK and Cancel
# 2 = Abort, Ignore, Retry
# 3 = Yes, No, Cancel
# 4 = Yes or No
# 5 = Retry, Cancel
# The following numbers can further change the icon style of
# the text box, and one of these numbers can be added to the
# number you pick above:
# 16 = Critical Error
# 32 = Question
# 48 = Exclamation
# 64 = Information
# The last number tells the function to wait N seconds before
# automatically closing the dialog. If this number is zero,
# then the dialog will remain open until the user clicks on
# one of the buttons.
#
# After the dialog is closed, the function will return
# one of the following values:
# 0 = Dialog failed to display
# 1 = OK button was clicked
# 2 = Cancel button was clicked
# 3 = Abort button was clicked
# 4 = Retry button was clicked
# 5 = Ignore button was clicked
# 6 = Yes button was clicked
# 7 = No button was clicked
# 8 = Timeout expired and dialog was closed automatically
#
# Usage: INTEGER = WinDialog(MESSAGE, [TITLE, [STYLE, [TIMEOUT]]])
#
sub WinDialog
{
$^O =~ m/MSWIN/i or return 9;
my $TEXT = defined $_[0] ? $_[0] : '';
my $TITLE = defined $_[1] ? $_[1] : "Perl $]";
my $STYLE = defined $_[2] ? $_[2] & 0x77 : 0;
my $TIMEOUT = defined $_[3] ? int($_[3]) : 0;
(($STYLE & 15) > 5) and $STYLE &= 0x70;
# Escape special chars
$TEXT =~ s/([\\'\x00-\x1F\x7F-\xFF]{1})/"\\x" . sprintf('%.2x', ord
+($1))/ge;
$TITLE =~ s/([\\'\x00-\x1F\x7F-\xFF]{1})/"\\x" . sprintf('%.2x', ord
+($1))/ge;
return RunJS("E=0;try{W=new ActiveXObject('WScript.Shell');E=W.Popup
+('$TEXT',$TIMEOUT,'$TITLE',$STYLE);if(E<0)E=8;}catch(e){} WScript.Qui
+t(E);") >> 8;
}
########################################################
# Usage: STATUS = CreateFile(FILENAME, [STRINGS...])
sub CreateFile
{
@_ or return 0;
my $F = shift;
defined $F && length($F) or return 0;
$F =~ m/[\x00-\x1F|<>*?]{1}/ and return 0;
local *FILE;
open(FILE, ">$F") or return 0;
binmode FILE;
foreach (@_)
{
defined $_ && length($_) or next;
print FILE $_;
}
close FILE;
return -f $F;
}
########################################################
# Usage: EXIT(BEEPS)
sub EXIT
{
my $COUNT = GetInt($_[0]);
$COUNT and BEEP($COUNT);
exit;
}
########################################################
# Usage: BEEP(COUNT)
sub BEEP
{
my $COUNT = GetInt($_[0]);
while ($COUNT-- > 0)
{
print "\x07";
Wait250(2);
}
}
########################################################
# Usage: Wait250(COUNT)
sub Wait250
{
my $COUNT = GetInt($_[0]);
$COUNT and select(undef, undef, undef, $COUNT * 0.25);
}
########################################################
# Usage: INTEGER = GetInt(NUMBER)
sub GetInt
{
no warnings;
my $N = (defined $_[0]) ? int($_[0]) : 0;
if ($N < 0) { $N = 0; } elsif ($N > 65535) { $N = 65535; }
return $N;
}
########################################################
Currently, 4 people have upvoted and 6 people have down-voted this post, proving my point I made earlier... https://perlmonks.com/?node_id=11163797 |