Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

How to Resize a Window in M$ Windows?

by NateTut (Deacon)
on Feb 09, 2011 at 17:49 UTC ( [id://887247]=perlquestion: print w/replies, xml ) Need Help??

NateTut has asked for the wisdom of the Perl Monks concerning the following question:

I'm writing an application that will manipulate some Putty Sessions. So far I am using Win32::GuiTest to send commands to the Putty Window. I read the Putty log for the output (anybody know how I can scrape the test directly from the Putty window?).

Eventually I'm going to be manipulating two Putty windows and I want to tile them. I have the screen size and I would like to resize the Putty window to full screen height & 0.5 Screen width. I have the window handle I just need a function to call to resize the window. I've been searching around CPAN & Google all morning.

Code is below. Thanks.
use strict; use warnings; use constant error => -1; use constant noerror => 0; use constant false => 0; use constant true => 1; $| = true; # # Modules Used # use Data::Dumper; use File::Basename; use File::ReadBackwards ; use File::Tail; use Win32::GUI(); use Win32::GuiTest qw(:ALL); # # Who am I? # my $MyName = (fileparse($0, '\..*'))[0]; # # Globals # my $LogFilesTail = undef(); # # ReadTails # # Read Latest File Updates from File::Tailed files # # Arguments: \@TailedLogFiles # # Returns: undef if something went awry, otherwise $TailedLines # $TailedLines = # [ # { # 'File1' => # [ # 'Line1' # , 'Line2' # . # . # . # , 'LineN' # ] # # } # ]; # sub ReadTails { my($TailedLogFiles) = shift; my $TimeOut = 5; my $TailedLines = undef(); my $Found = true; while (true) { my @Pending; ($Found, undef, @Pending) = File::Tail::select(undef, undef, und +ef, $TimeOut, @$TailedLogFiles); if($Found) { foreach (@Pending) { # print $_->{"input"}." (".localtime(time).") ".$_->read; # print(__FILE__ . '(' . __LINE__ . ')' . "\[$_->{buffer}\ +]\n"); push(@{$TailedLines->{$_->input}}, $_->{buffer}); } last(); } } return($TailedLines); } # # FindNewestlog # # Find Newest Putty Log File # # Arguments: $PuttyLogDirectory # # Returns: error if something went awry, otherwise $PuttyLogFileName # sub FindNewestlog { my($PuttyLogDir) = shift; my $DirH; opendir($DirH, $PuttyLogDir) or return(undef()); my @Files = readdir($DirH); closedir($DirH); my $NewestFile; $NewestFile->{'Name'} = undef(); $NewestFile->{'Date'} = 0; foreach my $File (@Files) { if((-d $File)) { next(); } elsif($File =~ /\d+\-.*\.log/) { my $CreateDate = (stat(($PuttyLogDir . $File)))[10]; if($CreateDate > $NewestFile->{'Date'}) { $NewestFile->{'Name'} = $PuttyLogDir . $File; $NewestFile->{'Date'} = $CreateDate; } else { next(); } } else { next(); } } return($NewestFile->{'Name'}); } # # Minus # # Subtract Two Arrays # # Arguments: $Array1 # $Array2 # # Returns: error if something went awry, otherwise $Difference # sub Minus { my($Array1, $Array2) = @_; # "Subtract" (remove) elements of @minus from @list: # Thanks to PerlMonks tye & princepawn my %dup; @dup{@$Array2}= (); my @list = @$Array1; @list = grep { not exists $dup{$_} } @list; return(\@list); } # # StartPutty # # Start a Putty Session and Return the Window Handle # # Arguments: $SessionName - Putty Session Name # $UnixId - Unix user name # $UnixPassword - Unix Password # $UnixPrompt - Command line Prompt # $PuttyLogDirectory - Local Directory Where the Putty Log +s Can be Found # $LogFileTailArray - Array of Tail File Handles # # Returns: error if something went awry, otherwise $PuttyInfo # sub StartPutty { my($SessionName, $UnixId, $UnixPassword, $UnixPrompt, $PuttyLogDire +ctory, $LogFileTailArray) = @_; # # Start a New Putty Window # my $PuttyInfo; my @WindowsBefore = FindWindowLike(undef, $SessionName); print(__FILE__ . '(' . __LINE__ . ')' . "Starting Putty Session:\[$ +SessionName\]\n"); system("start \"$SessionName\" \"C:\\Program Files\\PuTTY\\putty.ex +e\" -load \"$SessionName\" -l f17mg0 -pw \"$UnixPassword\""); sleep(3); my @WindowsAfter = FindWindowLike(undef, $SessionName); my $Difference = Minus(\@WindowsAfter, \@WindowsBefore); # # Find the New Putty Window # if(scalar(@$Difference) == 1) { # # Get the New Putty Window's Handle # print(__FILE__ . '(' . __LINE__ . ')' . "Getting Putty Window Ha +ndle\n"); $PuttyInfo->{'WindowHandle'} = $Difference->[0]; my $SavedActiveWindow = GetActiveWindow($PuttyInfo->{'WindowHand +le'}); # # Get Putty Log File Name # $PuttyInfo->{'LogFileName'} = FindNewestlog($PuttyLogDirectory); print(__FILE__ . '(' . __LINE__ . ')' . "\$PuttyInfo->{'LogFileN +ame'}:\[$PuttyInfo->{'LogFileName'}\]\n"); if(defined($PuttyInfo->{'LogFileName'})) { # # Start Tailing log File # my $LogFileTail = File::Tail->new ( 'name' => $PuttyInfo->{'LogFileName'} ); print(__FILE__ . '(' . __LINE__ . ')' . "Log File Tail Receiv +ed...\n"); if($LogFileTail) { $PuttyInfo->{'Tail Handle'} = $LogFileTail; push(@$LogFileTailArray, $PuttyInfo->{'Tail Handle'}); while(1) { print(__FILE__ . '(' . __LINE__ . ')' . "Reading Log Fi +le...\n"); my $TailData = ReadTails($LogFileTailArray); if(grep(/$UnixPrompt/, @{$TailData->{$PuttyInfo->{'LogF +ileName'}}})) { print(__FILE__ . '(' . __LINE__ . ')' . "Found:\[$Un +ixPrompt\].\n"); last(); } else { print(__FILE__ . '(' . __LINE__ . ')' . "\[$UnixProm +pt\] Not Found\n"); } } # # sudo to admin id # SetActiveWindow($PuttyInfo->{'WindowHandle'}); SendKeys("exec sudo su - $UnixId~"); sleep(1); SendKeys($UnixPassword . '~'); sleep(1); SendKeys('. ./p~'); SetActiveWindow($SavedActiveWindow); } else { $PuttyInfo = undef(); } } else { $PuttyInfo = undef(); } } else { $PuttyInfo = undef(); } return($PuttyInfo); } # # StopPutty # # Stop a Putty Session # # Arguments: $PuttyInfo - Putty Session Hash Ref # # Returns: Nothing worth getting bothered about # sub StopPutty { my ($PuttyInfo) = shift; my $SavedActiveWindow = GetActiveWindow($PuttyInfo->{'WindowHandle' +}); SetActiveWindow($PuttyInfo->{'WindowHandle'}); SendKeys('exit~'); SetActiveWindow($SavedActiveWindow); } # # Main # my $UnixId = 'MyId'; my $UnixPassword = 'MyPW'; my $UnixPrompt = '@SystemName'; my $SessionName = 'System Name'; my $PuttyLogDirectory = "C:\\Log\\"; my $PuttyOldLogDirectory = "C:\\Log\\Old"; my $TailedPuttyLogs; my $PuttyInfo = StartPutty($SessionName, $UnixId, $UnixPassword, $Unix +Prompt, $PuttyLogDirectory, $TailedPuttyLogs); print(__FILE__ . '(' . __LINE__ . ')' . "Active Window:\[$PuttyInfo->{ +'WindowHandle'}\] PuttyLogFileName:\[$PuttyInfo->{'LogFileName'}\]\n" +); WMSetText($PuttyInfo->{'WindowHandle'},"Test Primary"); SetActiveWindow($PuttyInfo->{'WindowHandle'}); my @WindowCorners = GetWindowRect($PuttyInfo->{'WindowHandle'}); # print("\@WindowCorners:\[" . (Dumper(\@WindowCorners)) . "\]\n"); my ($ScrWidth, $ScrHeight) = GetScreenRes(); print(__FILE__ . '(' . __LINE__ . ')' . "\$ScrWidth:\[$ScrWidth\] \$Sc +rHeight:\[$ScrHeight\]\n"); bless($PuttyInfo->{'WindowHandle'}, 'Win32::GUI'); $PuttyInfo->{'WindowHandle'}->Resize(($ScrWidth * .5), $ScrHeight); StopPutty($PuttyInfo); __END__

Replies are listed 'Best First'.
Re: How to Resize a Window in M$ Windows?
by afoken (Chancellor) on Feb 09, 2011 at 23:21 UTC

    You seem to abuse PuTTY as a way to automatically send commands via SSH to a remote host. Why don't you use one of the SSH libraries available at CPAN? If you can't use them, why don't you use plink.exe?

    Funny that you still assume that one will need to enter a password to log in to a remote system. I prefer using public key systems, no need to enter a password all the times.

    sudo su - $userid looks old. sudo should know the -i parameter, giving you a login session without the extra work of invoking su. It should also know the -u parameter to select a user different from root, by name or by UID.

    Depending on how sudo was configured, it will not always ask for a password, but your StartPutty function does not check for that condition. Instead, it blindly enters the password, already having root permissions. Let's hope no user has "rm -rf /" as password.

    The code around sudo has two "long" sleeps, during that time, some nasty popup could steal the focus. That would completely break your code, because the keys you send never arrive at the server. It will still sit there waiting for a user command or a password when you try to feed it root commands. You should at least check for prompts. Better, get rid of those remote-controlling attempts. It can't work reliable. Create an SSH connection from within perl or use the plink.exe helper when you can't use an SSH library.

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
Re: How to Resize a Window in M$ Windows?
by kejohm (Hermit) on Feb 10, 2011 at 04:02 UTC

    Since you have a handle, not a Win32::GUI object, you can't call Resize() as a method, you have to call it as a function, passing the handle as the first argument. Example:

    Win32::GUI::Resize($handle, $new_width, $new_height);

    The same goes for most other methods in the Win32::GUI module.

      But he does bless the handle :) Based on
      $ perl -MDDS -MWin32::GUI -e " Dump( Win32::GUI::Window->new ) " $Win32_GUI_Window1 = bless( { -accel => 0, -handle => 1442212, -name => '#118a214', -type => 0 }, 'Win32::GUI::Window' );
      I would use
      $PuttyInfo->{'Window'} = bless( { -accel => 0, -handle => $PuttyInfo->{'WindowHandle'}, -name => 'something', -type => 0 }, 'Win32::GUI::Window' ); $PuttyInfo->{'Window'}->Resize(($ScrWidth * .5), $ScrHeight);

        My own experience has taught me not to try create a Win32::GUI object from a handle, as you might do something wrong, or there might be other things at work that you might miss (I think the module actually ties the hash object to allow some magic). Best just let the module look after all that. The function style works fine, albeit a little cumbersome.

Re: How to Resize a Window in M$ Windows?
by NateTut (Deacon) on Feb 10, 2011 at 17:36 UTC
    Thanks for the help. I'm abusing putty so badly because once I send the commands to Putty I want the user to be able to use the Putty session to enter their own commands.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others learning in the Monastery: (5)
As of 2024-04-25 10:24 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found