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

I'm trying to send emails via Outlook 2007 after upgrading from Outlook 2003 and am coming across some errors. Below is the code that I have. Currently I have an issue with "$msg = $session->Outbox->Messages->Add();", but I forsee that I may have more issues; for instance "$recipient = $msg->Recipients->Add();". Any help or guidance would be appreciated.
use OLE; use Win32::GUI; use Win32::GuiTest; use Thread; use strict; my ($pwd, $msgFileNm) = @ARGV; shift; shift; open IN, "<".$msgFileNm or die "Can't open file of messages >$msgFileN +m< : $!"; my $session; $session = Win32::OLE->new('Outlook.Application'); die unless $session; #get the Inbox folder my $namespace = $session->GetNamespace("MAPI"); my $folder = $namespace->GetDefaultFolder("olFolderTasks"); # Create a new MAPI session #my $session = Win32::OLE->new("MAPI.Session") or die "Failed to creat +e a MAPI Session: $!"; # Logon to server my $res = $session->Logon('Default Outlook Profile', $pwd);# or die "C +ould not log onto Outlook $!"; my $thread1; print "SendEmailFromFileViaMAPIOutlook.pl ".localtime(time)."\n"; my $msg; my $recipient; my ($to, $sub, $bdy, $cc) = getNextMsg(); while($to gt ''){ $thread1 = Thread->new(\&handleMessageBoxes); # Create a new message $msg = $session->Outbox->Messages->Add(); # Add the recipient and resolve the address $recipient = $msg->Recipients->Add(); $recipient->{Name} = $to; $recipient->{Type} = 1; # 1-to, 2-cc, 3-bcc #$thread1 = Thread->new(\&handleMessageBoxes); $recipient->Resolve(); if(length($cc) > 0){ $recipient = $msg->Recipients->Add(); $recipient->{Name} = $cc; $recipient->{Type} = 2; $recipient->Resolve(); } # Add your text $msg->{Subject} = $sub; #"Email Test"; $msg->{Text} = $bdy; # Send the email $msg->Update(); # 1st argument = save copy of message # 2nd argument = allows user to change message w/dialog box before + sent # 3rd argument = parent window of dialog if 2nd argument is True $msg->Send(0, 0, 0); print "To: $to , cc: $cc Subject: $sub\n"; $thread1->detach(); print "$to\n"; $to = $sub = $bdy = $cc = ''; ($to, $sub, $bdy, $cc) = getNextMsg(); } # Log off $session->Logoff(); sub getNextMsg{ my (@flds, $to, $sub, $bdy, $cc); $to = $sub = $bdy = $cc = ''; while(<IN>){ if($_ =~ /^To:/){ @flds = split(/:/, $_); $to = $flds[1]; chom +p $to; next; } if($_ =~ /^Sub:/){ @flds = split(/:/, $_); $sub = $flds[1]; ch +omp $sub; next; } if($_ =~ /^Cc:/i){ @flds = split(/:/, $_); $cc = $flds[1]; cho +mp $cc; next; } if($_ =~ /^\+\+\+\+\+\+\+\+\+\+/){ last; } $bdy .= $_; } return $to, $sub, $bdy, $cc; } sub handleMessageBoxes{ sleep 1; my $securityHandle = 0; my $cnt = 0; while(not($securityHandle) && ($cnt++ < 10)){ $securityHandle = &waitForSecurityWindow(); } &respondToMessageBox($securityHandle, 't,t,t,e'); sleep 1; my $securityHandle = 0; my $cnt = 0; while(not($securityHandle) && ($cnt++ < 10)){ $securityHandle = &waitForSecurityWindow(); } sleep 6; &respondToMessageBox($securityHandle, 't,t,e'); } sub respondToMessageBox{ my ($hndl, $keySeq) = @_; while($hndl != Win32::GUI::GetForegroundWindow){ Win32::GUI::SetForegroundWindow($hndl); Win32::GUI::Enable($hndl); } my @keys = split(',', $keySeq); foreach my $k (@keys){ my $kval = ($k eq 't') ? "{TAB}" : ($k eq 'e') ? "{ENTER}" : ( +$k eq 's') ? "{SPACE}" : ''; if($kval ne ''){ Win32::GuiTest::SendKeys($kval); } } } sub waitForSecurityWindow{ my $messageClass = "#32770"; my $windowName = 'Microsoft Office Outlook'; return Win32::GUI::FindWindow(undef, $windowName); }

Replies are listed 'Best First'.
Re: Send Outlook 2007 email
by zentara (Cardinal) on Nov 11, 2009 at 16:14 UTC
      Sorry forgot. Before it would just send all the emails that were in a txt file, and since updating I still want to send from the same txt file but am getting the following error:
      Can't call method "Messages" on an undefined value at P:\bin\SendEmail +FromFileViaMAPIOutlook_v2.pl line 35, <IN> line 49. A thread exited w +hile 2 threads were running, <IN> line 49.
        ...just hazarding a guess, based on the fact that the you are using threads, and the error message....

        it seems line35 is Can't call method "Messages" on an undefined value... and what might that value be?..... i can't be sure it's line 35, but it looks like

        # Create a new message $msg = $session->Outbox->Messages->Add();
        ...so it seems that either $session is not shared (i.e. available in the thread )...or...$session->Outbox is not returning what you think with the new Outlook version try:
        print "$session, $session->Outbox\n"; $msg = $session->Outbox->Messages->Add();
        .... some possible things to watch for?..... $session->Outbox is now returning an array or something different from the earlier version..... or the new Outlook isn't thread safe, or something ..... by the way, the code looks like complete crap as far as thread variable management goes.....you seem to rely on being able to make $session a global object, and hoping the global nature extends into the thread..... the fact it even worked earlier is surprising..... but i don't do win32....so i just observe

        I'm not really a human, but I play one on earth.
        Old Perl Programmer Haiku