[Date Prev][Date Next][Thread Prev][Thread Next] [Search] [Date Index] [Thread Index]

RE: [MacPerl] Launching a script from another script??



Chris,

> Here is a script that will run another MacPerl by launching 
> another copy of
> the MacPerl app (creating it if need be) and then telling it 
> to Do Script,
> and passing arguments as appropriate.

This works great, thanks!

If you'll indulge me a little further, I am now trying to send input to the
launched script.  After reading Matthias' documentation on the various "Do
Script" modes in MacPerl.FrontEnd, I wrote a similar Perl script (see below)
which attempts to send input to the launched script via a McPL/DATA event. I
can verify that the launched script is successfully reading the input, but I
cannot get output back from the launched script. 

One thing that bothers me is that Matthias' example shows the outgoing
McPL/DATA event as follows:

	McPL/DATA{INPT:{"----","--More--
	"}}

My DATA event doesn't have the enclosing INPT:{}. I'm not sure whether this
is important. Also, it is not clear to me how the launching script should
indicate EOF on the input.



#!perl -w

use File::Copy;
use Mac::AppleEvents;
use Mac::Files;
use Mac::Processes;
use strict;

my $wait = kAEWaitReply; # kAENoReply or kAEWaitReply
my $input = "This is test input.\n";
my $response = run_script_with_stdin($input, "test-input.pl", "a", "b",
"c");

if ($response)
{
	print "Response:\n";
	print $response;
}
else
{
	print "No response!\n";
}


sub run_script_with_stdin
{
	my $input = shift;
	my $script = shift;
	my @args = @_;

	my ($list, $evt, $sdevt, $rep, $stdout, $reply);
	my $done;

	# Build command-line arg list
	$list = AECreateList('',0);
	AEPut($list, 1, typeAlias, NewAliasMinimal($script)->get) or die
$^E;
	for (0..$#args)
	{
		AEPut($list, $_ + 2, typeChar, $args[$_]) or die $^E;
	}
	
	# Launch a copy of MacPerl ( if necessary)
	my $psn = launch_macperl_copy();
	
	# Install a McPL/SASE event handler
	$done = undef;
	$AppleEvent{'McPL', 'SASE'} = \&HandleSASE;

	# Create the event
	$evt = AEBuildAppleEvent(	'misc', 'dosc',
typeProcessSerialNumber, $psn,
	
kAutoGenerateReturnID, kAnyTransactionID, 
								'MODE:RCTL')
or die $^E;
	
	AEPutParam($evt, keyDirectObject, typeChar, 'SASE:{evcl:McPL,
evid:SASE}') or die $^E;

	
	# Add cmd-line args to the event and send it off
	AEPutParamDesc($evt, keyDirectObject, $list) or die $^E;
	$rep = AESend($evt, kAEWaitReply) or die $^E;
	
	print "evt: ", AEPrint($evt), "\n";
	print "rep: ", AEPrint($rep), "\n";

	AEDisposeDesc($rep);

	# Wait for the SASE event
	sleep(1) while(not $done);
	
	# Send stdin via a "Send Data" event
	$sdevt = AEBuildAppleEvent(	'McPL', 'DATA',
typeProcessSerialNumber, $psn,
	
kAutoGenerateReturnID, kAnyTransactionID, '') or die $^E;
								
	# Add stdin to the event
	AEPutParam($sdevt, keyDirectObject, typeChar, $input) or die $^E;
	# Send it off
	print "sdevt: ", AEPrint($sdevt), "\n";
	$rep = AESend($sdevt, kAEWaitReply) or die $^E;

	print "rep: ", AEPrint($rep), "\n";
	
	# Trap stdout
	if ($stdout = AEGetParamDesc($rep, keyDirectObject))
	{
		print "stdout=$stdout\n";
		$reply = $stdout->get if $stdout->get;
		AEDisposeDesc($stdout);
	}

	# Clean up	
	AEDisposeDesc($list);
	AEDisposeDesc($sdevt);
	AEDisposeDesc($evt);
	AEDisposeDesc($rep);
	
	return $reply;

	sub HandleSASE
	{
		my ($event) = @_;

		print "HandleSASE: event: ", AEPrint($event), "\n";
		$done = 1;
	}


}


sub launch_macperl_copy
{
	my ($macperl, $copy_spec, $copy, $count, $psn);
	
	$macperl = "$ENV{MACPERL}$^X";
	$copy_spec = "$macperl copy ";
	$count = 1;
	
	do
	{
		$copy = $copy_spec.$count;
		$count++;
	} until (!get_psn($copy));

	copy($macperl, $copy) unless -e $copy;
	
	my $lp = new LaunchParam(	launchAppSpec=>$copy,
	
launchControlFlags=>(launchContinue|launchNoFileFlags|launchDontSwitch));
	LaunchApplication($lp) or die $^E;
	
	return unless ($psn = get_psn($copy));
	
	$psn = pack('ll', $psn/(2**32), $psn%(2**32));
	
	return $psn;
}


sub get_psn
{
	my $app = shift;
	my $psn = undef;
	foreach (keys %Process)
	{
		$psn = $_ if $Process{$_}->processAppSpec eq $app;
		last if $psn;
	}
	return $psn;
}


-------------------------------
The output looks like this:


evt: misc\dosc{'----':[alis(...), "a", "b", "c"], MODE:RCTL, &inte:cans,
&timo:3600}
rep: aevt\ansr{}
HandleSASE: event: {McPL\SASE}
sdevt: McPL\DATA{'----':"This is test input.
"}
rep: aevt\ansr{WANT:['----'], DONE:bool(00)}



Thanks again,
Todd



===== Want to unsubscribe from this list?
===== Send mail with body "unsubscribe" to macperl-request@macperl.org