use strict; use Thread; use Win32::OLE::Const 'Microsoft Outlook'; use Win32::OLE; use Win32::OLE qw(in with); use Win32::GUI; use Win32::GuiTest; use IO::File; use Getopt::Long; use File::Basename; use POSIX qw(tmpnam); #$|++; ## These variable will be used to store the command line argufromnts my $SAVEDIR = $ARGV[0]; my $ATTACH_PATH = $SAVEDIR."\\attachments\\"; my $ITEMS; do { mkdir $SAVEDIR or die "Can't mkdir $SAVEDIR $!\n" } unless -d $SAVEDIR; do { mkdir $ATTACH_PATH or die "Can't mkdir $ATTACH_PATH $!\n" } unless -d $ATTACH_PATH; sub chkOpts { if(!$ARGV[0]) { print "\n",'Please enter the directory path for eg: exportOutlook D:/output so that the output files can be stored in that location.',"\n"; exit; } } my $thr1 = Thread->new(\&handleOutlookSecurity); 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 executed. # Else it'll pend. { my $messageClass = "#32770"; my $winName = "Microsoft Outlook"; return Win32::GUI::FindWindow($messageClass,$winName); #c } sub clearSecurityWindow # this method brings the security window on top of all the others, hence focusing it # and sends it a series of keystrokes in order to validate it. { my $securityHandle = shift; while ($securityHandle!=Win32::GUI::GetForegroundWindow())#c { Win32::GUI::SetForegroundWindow($securityHandle);#c Win32::GUI::Enable($securityHandle);#c } # now send key sequence that will allow maximum time for code to run # 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. One more tab brings us to Yes. A keypress on the End key will # select maximum time. Then a return key will validate our choice # 2 tabs - spacebar - 2 tab - one end - one return Win32::GuiTest::SendKeys("{TAB}"); Win32::GuiTest::SendKeys("{TAB}"); Win32::GuiTest::SendKeys("{SPACEBAR}"); Win32::GuiTest::SendKeys("{TAB}"); #Win32::GuiTest::SendKeys("{DOWN}"); #Win32::GuiTest::SendKeys("{DOWN}"); Win32::GuiTest::SendKeys("{TAB}"); Win32::GuiTest::SendKeys("{END}"); Win32::GuiTest::SendKeys("{ENTER}"); } sub clearSecurityWindow2 # this method does the same as clearSecurityWindow but handles the second security window. { my $securityHandle = shift; while ($securityHandle!=Win32::GUI::GetForegroundWindow()) #c { Win32::GUI::SetForegroundWindow($securityHandle); #c Win32::GUI::Enable($securityHandle); #c } Win32::GuiTest::SendKeys("{TAB}"); Win32::GuiTest::SendKeys("{TAB}"); Win32::GuiTest::SendKeys("{ENTER}"); } sub handleOutlookSecurity { # We don't need to sleep but just to be safe sleep 3; my $securityHandle = 0; while (not ($securityHandle)) # detects Outlook's popup window that asks whether access should be granted to { $securityHandle = findSecurityWindow(); # wait for security window to pop-up... } # window has been found - clear it clearSecurityWindow($securityHandle); # We need the "Yes" button to be active sleep 10; $securityHandle = 0; while (not ($securityHandle)) { $securityHandle = findSecurityWindow(); # wait for security window to pop-up... } # window has been found - clear it clearSecurityWindow2($securityHandle); } sub main { # init OLE, COINIT_OLEINITIALIZE required when using MAPI.Session objects Win32::OLE->Initialize(Win32::OLE::COINIT_OLEINITIALIZE); #die Win32::OLE->LastError(),"\n" if Win32::OLE->LastError( ); # Create a new MAPI session my $OUTLOOK = Win32::OLE->new('Outlook.Application') or die "Could not instatiate Outlook: " . Win32::OLE::LastError(); my $NS = $OUTLOOK->GetNamespace("MAPI") or die "Could not get namespace: " . Win32::OLE::LastError(); for my $parent ( 1..$NS->Folders->Count ) { recurse_folders( $NS->Folders($parent), $parent ); } sub recurse_folders { my ($folder, $parent) = @_; return if $folder->DefaultItemType != olMailItem; # not a mail folder #my $fh = get_fh("$parent/".$folder->Name); # if ( ("$parent/".$folder->Name) =~ m/$ROOT_FOLDER/i ) #{ #printf "\n\nFolder: %s\nTotal entries: %s\n", # "$parent/".$folder->Name, $folder->Items->Count if $DEBUG; for my $i (1..$folder->Items->Count) { printf "Processing %d\r", ++$ITEMS; my $message = $folder->Items->Item($i); next unless $message->Class == olMail; # mail item #next if $DEBUG and $DEBUG < 4 ; #(my $body = $message->Body || '' ) =~ s/\r//g; (my $body = $message->Body || '' ); my $attach = $message->Attachments; my $subject = $message->Subject; my $splitSubject = substr($subject,0,30); $splitSubject =~ s/\W/ /g; my $outputFile = $SAVEDIR.'\\'.$splitSubject."_".$ITEMS.".txt"; open(MESSAGEFILE, '>',$outputFile) or print $outputFile," $!"; print MESSAGEFILE $body; close(MESSAGEFILE); #Store the attachments if any of the current mail item for my $attach_index (1..$attach->Count) { my $attachment = $attach->item($attach_index); my $filename = $attachment->Filename; #print "Attachment == ",$filename,"\n"; my $saveas = $ATTACH_PATH.$ITEMS."_".$filename; #print "saving attachment '$filename' to '$saveas'...\n"; $attachment->SaveAsFile($saveas); warn "error saving attachment $filename to $saveas" if !-e $saveas; } } #} # recursive tree walk if ($folder->Folders and $folder->Folders->Count) { for my $i (1..$folder->Folders->Count) { recurse_folders($folder->Folders($i),"$parent/".$folder->Name); } } } } chkOpts(); main();