http://qs321.pair.com?node_id=185757
Category: Win32 stuff
Author/Contact Info Pierre Antonini pierre.antonini@kioskemploi.com
Description: The Outlook E-mail Security Update provides additional levels of protection against malicious e-mail messages. The update changes the way that Outlook can be controlled programmatically (Microsoft knowledgebase Q262701). Sending mail and accessing the Adress book display a dialog box asking you to confirm the action Dmitry Streblechenko at http://www.dimastr.com as released Redemption (http://www.dimastr.com/redemption/), an OLE object that works around limitations imposed by the Outlook Security Patch. Here is an example of using Redemption with Perl for sending e-mails :
#!c:/perl/bin/perl

use locale;
use warnings;
use Win32::OLE;
use Win32::OLE::Const;
use Win32::OLE::Const 'Microsoft Outlook';

$MailProps{'to'}   = "sendto\@myserver.com";
$MailProps{'cc'}   = "sendcc\@myserver.com";
$MailProps{'bcc'}  = "sendbcc\@myserver.com";
$MailProps{'importance'} = 2;  # 2=high, 1=normal, 0=low
$MailProps{'subject'} = "Message subject";
$MailProps{'body'} = "Message body";
@Attachement = ("d:\\test.doc");
$MailProps{'attachments'} = \@Attachement;

$Error = &OUT_SendMail (\%MailProps);
print "Return error : ".$Error."\n";
exit;

sub OUTLOOK_SendMail
{
   my ($rMailProps) = @_;

   my $Application = new Win32::OLE('Outlook.Application');
   my $MailItem = $Application->CreateItem(0);  # 0 = mail item.
   unless (defined $MailItem)
   {
      print "Outlook is not running, cannot send mail.\n" if $Debug;
      return 1;
   }

   # Create a Redemption object
   my $SafeMailItem = new Win32::OLE('Redemption.SafeMailItem');
   unless (defined $SafeMailItem)
   {
      print "Redemption is not running, cannot send mail.\n" if $Debug
+;
      return 1;
   }
   # Set Item property of the Redemption object
   $SafeMailItem->{'Item'} = $MailItem;

   $SafeMailItem->{'To'} = join(";", split(/[ ,;]+/, $rMailProps->{'to
+'}));
   $SafeMailItem->{'Cc'} = $rMailProps->{'cc'} if (exists $rMailProps-
+>{'cc'});
   $SafeMailItem->{'Bcc'} = $rMailProps->{'bcc'} if (exists $rMailProp
+s->{'bcc'});
   $SafeMailItem->{'Subject'} = $rMailProps->{'subject'} || '[No Subje
+ct]';
   $SafeMailItem->{'Body'} = $rMailProps->{'body'} || "\r\n";
   $SafeMailItem->{'Importance'} = (exists $rMailProps->{'importance'}
+)? $rMailProps->{'importance'} : 1;

   if (exists $rMailProps->{'attachments'})
   {
      my $attach = $SafeMailItem->{'Attachments'};

      foreach my $attach_file (@{ $rMailProps->{'attachments'} })
      {
         if ($attach_file and -f $attach_file)
         {
            $attach->add($attach_file);
         }
      }
   }
   $SafeMailItem->Send();
   return 0;
}
Replies are listed 'Best First'.
Re: Win32::OLE Outlook and E-mail security update
by Foggy Bottoms (Monk) on Aug 06, 2003 at 14:17 UTC
    Unfortunately you need to pay $200 (USD) to use the dll in one your programs whether it be commercial or for internal use. It seems very interesting but I'll have to look for an alternative...
Re: Win32::OLE Outlook and E-mail security update
by Foggy Bottoms (Monk) on Aug 08, 2003 at 14:44 UTC
    There is another tricky way to override security problems in Outlook...
    Since the main problem is that there's a window that pops up and freezes the code, all we need to do is run a parallel and independent process that'll detect that pop-up window and validate it.
    Now how in the world ??!??! It's all rather simple - but not very academic. All you have to do is bring that window to the foreground, activate the maximum time length during which perl code will be authorized to run (10 mns in Outlook 2002) and there you go.
    Use the package Win32::GUITest to send keys to the window. By sending the sequence (tab twice then space then tab then end then enter) you're actually selecting maximum time option and validating it...
    You can try it out - it works just fine. Enjoy - and there's $200 saved :
    use Win32::OLE qw(in with); use Win32::GUI; use Win32::GuiTest; sub findSecurityWindow # this method detects whether a security window popped up in Outlook. +If it is # the case, it needs to be processed so that the script can be execute +d. # Else it'll pend. { my $messageClass = "#32770"; my $winName = "Microsoft Outlook"; return Win32::GUI::FindWindow($messageClass,$winName); } sub clearSecurityWindow # this method brings the security window on top of all the others, hen +ce focusing it # and sends it a series of keystrokes in order to validate it. { my $securityHandle = shift; print "shandle : $securityHandle\n"; # debug purposes while ($securityHandle!=Win32::GUI::GetForegroundWindow()) { #Win32::GUI::BringWindowToTop($securityHandle); # doesn't seem e +nough so let's focus it as well #Win32::GUI::SetFocus($securityHandle); Win32::GUI::SetForegroundWindow($securityHandle); Win32::GUI::Enable($securityHandle); } print "foreground window : Win32::GUI::GetForegroundWindow()"; # now send key sequence that will allow maximum time for code to ru +n # The sequence is as follows : initially the no button is focused.. +. # One tab brings us to cancel, another tab to the time tick box # a spacebar hit will tick the box. Then a tab will select the drop +-down # list in order for us to choose the time length. A keypress on the + End key will # select maximum time. Then a return key will validate our choice # 2 tabs - spacebar - 1 tab - one end - one return Win32::GuiTest::SendKeys("{TAB}"); Win32::GuiTest::SendKeys("{TAB}"); Win32::GuiTest::SendKeys("{SPACEBAR}"); Win32::GuiTest::SendKeys("{TAB}"); Win32::GuiTest::SendKeys("{END}"); Win32::GuiTest::SendKeys("{ENTER}"); }

    Then all you need is to call
    my $securityHandle = 0; while (not ($securityHandle)) # detects Outlook's popup window that as +ks whether access should be granted to { # perl code to Outlook's inner properties. $securityHandle = LTG::dialog::findSecurityWindow(); # wait for sec +urity window to pop-up... print "shandle : $securityHandle\n"; # debug purposes } # window has been found - clear it LTG::dialog::clearSecurityWindow($securityHandle);
      Small Optim,

      Replace all those SendKeys with one:

      Win32::GuiTest::SendKeys('%y');

      I actually did pretty much the same save I have a separate script that that lives for 2 minutes who's sole purpose in life is to kills off that popup window. In the calling application I call Win32::Process::Create as a detached_process just before causing the window to popup.

      p1:..code.. p1:Win32::Process::Create(,'allow_outlook_send.pl',,,DETACHED_PROCESS, +) p2:started, on loop look for window p1:access outlook p1:hang on output p2:found window, click yes (till yes is available) p2:exit p1:got output p1:..code..
      TM
Re: Win32::OLE Outlook and E-mail security update
by Anonymous Monk on Jun 03, 2004 at 17:08 UTC
    #########################################################################################

    #- -- This program inspects the internet header of all Microsoft Outlook (2002 SP-2)  messages in the user-defined “MyAccount”

    #--  directory to determine if the email was sent to myaccount@charter.net   If this is not the case, then it is spam and

    #--  the program puts the email in the “Deleted Items” folder.  If the email was sent to myaccount@charter.net place

    #-- the email in the MyAccount->Filtered folder.  This program assumes Microsoft Outlook is running.  This program

    #-- does not cause the Outlook Security Window to open, so nothing to worry about.

    #-- Author – Eric C. Hansen, May 2004    eric.amerwood@charter.net

    ####################################################################################################

     

    use Win32::OLE;

    use Win32::GuiTest;

    use Win32::Clipboard;

     

      $OL                           = Win32::OLE->GetActiveObject('Outlook.Application');

      $NameSpace            = $OL->GetNameSpace("MAPI");

      $Inbox                       = $NameSpace->GetDefaultFolder(6);          #-- inbox folder

      $Deleted                   = $NameSpace->GetDefaultFolder(3);           #-- deleted items folder

      $Root                        = $Inbox->Parent();

      $MyAccount            = $Root->Folders("MyAccount");

      $MyAccountOK      = $MyAccount->Folders("Filtered");

      $Clip                          = Win32::Clipboard();

     

      @wins = Win32::GuiTest::FindWindowLike(0,"^Microsoft Outlook",'mspim_wnd32');       #-- mspim_wnd32 is the class

      Win32::GuiTest::SetForegroundWindow($wins[0]);

     

      $cnt=$MyAccount->Items->Count;     #-- get a count of messages in folder "MyAccount"

     

       while ($cnt > 0) {

     

            $Clip->Empty();       #-- empty the clipboard

     

            $MyAccount->Items($cnt)->Display;       #-- display/open message with index of $cnt in the MyAccount folder

           

            Win32::GuiTest::SendKeys("%Vp");                                                #-- open options dialog  ALT-V-p

            Win32::GuiTest::SendKeys("{TAB 6}");                                          #-- move down to internet header field

            Win32::GuiTest::SendKeys("{APP} {DOWN 2} {ENTER}");       #-- put internet header in clipboard

            Win32::GuiTest::SendKeys("{TAB}");                                             #-- move to Cancel Button

            Win32::GuiTest::SendKeys("{ENTER}");                                        #-- press Cancel Button

            Win32::GuiTest::SendKeys("%{F4}");                                           #-- close message   ALT-F4

     

            undef $text;

            $text=$Clip->Get();             #-- get clipboard contents

            $text=~tr/A-Za-z.@/*/c;       #-- convert all but listed valid characters to *

            $text=~tr/*//d;                    #-- now delete asterisks

            $text=lc($text);                   #-- convert to lowercase

         

            # -- now check for our email address in the internet header text

            if ($text !~ /myaccount\@charter\.net/) {

               $MyAccount->Items($cnt)->Move($Deleted);                 #-- move message to “Deleted Items” folder      

            } else {

               $MyAccount->Items($cnt)->Move($MyAccountOK);    #-- move message to “MyAccount->Filtered folder

            }

     

            $cnt--;

      }

     

     #--  end script