#!/unused/bin/perl
  BEGIN {(*STDERR = *STDOUT) || die;}
  use diagnostics;
  use warnings;
  use strict;
  
  =head
  
  Here's an usable/working example of using Win32::OLE to automate web-tasks.
  The application is that of starting the Juniper Secure Connect VPN.
  
  Background on the application:
  
    A VPN set up using Juniper Secure Connect times out after 20
    hours.  The process of establishing the Juniper VPN involves:
  
       a) loading the https "welcome page" and authenticating onself 
          by entering a username and password.
       b) possibly responding to a page asking about cancelling an 
          existing connection 
       c) pressing a button that actually starts the VPN
  
    Even though there are only three pages that confront a user, there
    are other pages loaded which the user does not see -- these pages
    have nothing in their body but have javascript that does something
    and loads a different page.  Also, the final page with the button
    to start the VPN is in javascript.  Because of the presence of
    javascript, the process of starting the Juniper VPN cannot be done
    nicely with WWW::Mechanize.
  
    Regarding step (b):  For some reason having to do with the logic
    within the cgi, this page may not show up when it is needed.
    Hence, the code below starts by terminating any on-going Juniper
    Secure Client session.  However, it is also the case that this
    page may show up when there is apparently no on-going session to
    terminate (as would happen when, for example, the user rebooted
    his PC without terminating an on-going Juniper Secure Client
    session.  
  
  References:
  
    http://library.n0i.net/programming/perl/pe-rlmonth/issue3/ole_controls.html 
    http://www.perl.com/lpt/a/916
    A recent post to this list by  Steven Manross responding to the
    topic "Replacing WWW::Mechanize with Win32::OLE via IE" 
   
  Even-though this code is usable as-is, I do have questions: 
  
    1) Would replacing replacing the routine handle_events by a 
       class buy anything?  If so, what? 
  
    2) How would one do error checking?  (I dislike doing calls 
       without checking the status after the call.)
  
    3) Pros and cons of looping via Win32::OLE->MessageLoop() and 
       looping via: 
           until ($Quit) 
           {
                Win32::OLE->SpinMessageLoop;
                Win32::Sleep(100);
           }
  
    4) What are Variants and what does it mean to automatically
       translate them to strings and numbers?
  
    5) How are the things in the table on the following page:
  
           
http://msdn.microsoft.com/workshop/author/dhtml/reference/objects/obj_document.asp
  
       related to perl-objects (scalars, arrays, hashes, classes etc.)?
  
       For example, if something is a hash, its keys can be listed 
       as follows:
  
       # list_hash($ie_object->Document->Body->All, 'object-document-body-all');
       sub list_hash
       {
          my $the_hash = shift;
          my $label    = shift;
       
          my %foo = (); 
          my @keys = ();
             %foo = %{$the_hash};
             @keys = sort keys %foo;
             print "\n\nkeys of $label $the_hash ", $the_hash, ":[EMAIL 
PROTECTED]";
       }
  
       How would one list all methods?
  
       (The curly braces in the following line from sub input_text 
           "$tag and $tag->{value} = $value;"
        are required -- since without them we have $tag->value which
        is a method that returns the current value!!!)
  
    --Suresh
  =cut
  
  use Win32::OLE qw(EVENTS in);
  use Win32::OLE::Variant;
  
  my $do_end_juniper  = 1;
  my $do_make_visible = 1;
  
  #-----------------------------------------------------
  
  end_juniper($do_end_juniper);
  
  my $number_of_loads = 0;
  
  my $file = 'https://secure.safe.com/safe_keeper/authenticate/welcome.cgi';
  my $ie   = Win32::OLE->new("InternetExplorer.Application") || 
               die "Could not start Internet Explorer.Application\n";
  
  Win32::OLE->WithEvents($ie,\&handle_events,"DWebBrowserEvents2");
  
  $ie->{visible} = $do_make_visible;
  $ie->Navigate($file);
  
  Win32::OLE->MessageLoop();
  
  sub handle_events 
  {
      my ($whatever, $event, @Args) = @_;
  
      if ($event eq "DocumentComplete") 
      {
          my $ie_object = shift @Args;
          print "URL: " . $ie_object->Document->URL . "\n";
  
          $number_of_loads++;
          if($number_of_loads > 10)
          {
              $ie_object->Quit();
          }
          if(! input_text($ie_object, 'username', 'the_user'))
          {
             input_text($ie_object, 'password', 'his_password');
             input_click($ie_object, 'button_authenticate');
          }
          input_click($ie_object, 'button_intermediate');
          if(! input_click($ie_object, 'button_final'))
          {
              $number_of_loads = 10;
          }
      }
      if ($event eq 'OnQuit') 
      {
          Win32::OLE->QuitMessageLoop();
      }
  }
  
  sub input_text
  {
      my ($ie_object, $name, $value) = @_;
  
      my $tag = get_input_entry_item_by_name(@_);
  
      $tag and $tag->{value} = $value;
      return !$tag;
  }
  
  sub input_click
  {
      my $tag = get_input_entry_item_by_name(@_);
      
      $tag and $tag->click();
      return !$tag;
  }
  
  sub get_input_entry_item_by_name
  {
      my ($ie_object, $name) = @_;
      my $all                = $ie_object->Document->Body->All;
  
      foreach my $tag (in $all->tags('input'))
      {
         ($tag->name() eq $name) and return $tag; 
      }
      return undef; 
  }
  
  sub end_juniper
  {
    my $do_really = shift;
       $do_really or return;
  
    use Win32::GuiTest qw(GetChildWindows GetWindowText PushChildButton);
    
    for my $a_window ( GetChildWindows(0) ) 
    {
       my $foo = GetWindowText($a_window); 
       if($foo =~ m/Network\s+Connect/) 
       {
          PushChildButton($a_window, "Sign Out"); 
          last;
       }
    }
  }
  

_______________________________________________
Perl-Win32-Users mailing list
Perl-Win32-Users@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs

Reply via email to