in reply to How do I convert VBA script to Perl? - Using Win32::OLE
Years ago i made a Windows service which among other things also saved attachments from incoming messages from an inbox. Then I used IMAP as suggested already.
Also, if you search the internet for doing that with MAPI you learn that this can be a pain if possible at all inside your environment parameters (perl, in a service,...)
But because recently we decided we badly need that functionallity (IMAP will be disabled at some point in the future for the Exchange servers in question), I made a new attempt last month.
The following is a boiled down code from the real code I finally brought to production, which roughly resembles the VB in the OP.
The VB code from the OP remained as perl comments here for orientation, what happens about around that line.
Indented comments are all mine. If that is too distracting that VB code can be filtered out with something like
perl -ne "print unless /^#/" mapi.pl
#Option Explicit use strict; use warnings; use Win32::OLE qw(EVENTS); # Working with MAPI sessions needs other + threading model # # Private Sub Application_NewMail() sub application_newmail { my ($server, $alias) = @_; # connect to mailbox of CN $alias us +ing server $server my $mapikey = "$server\n$alias"; # # On Error GoTo GetAttachments_err #' Declare variables # Dim ns As NameSpace # Dim Inbox As MAPIFolder # Dim Item As Object # Dim Atmt As Attachment # Dim FileName As String # Dim i As Integer my $err; # Set ns = GetNamespace("MAPI") my $session = Win32::OLE->new(qw(MAPI.Session Logoff)) or return W +in32::OLE->LastError(); # Try to logon with dynamic profile under current account. # This may need a reasonable current CDO on your machine. $session->Logon(undef,undef,undef,1,undef,undef,$mapikey); return $err if $err = Win32::OLE->LastError(); # Set Inbox = ns.GetDefaultFolder(olFolderInbox) my $inbox = $mapi->Inbox(); return $err if $err = Win32::OLE->LastError(); # i = 0 # As described in MSDN, relying on Count for (possibly) "big" coll +ections (like items in folder) # can be problematic. Therefore we iterate with GetFirst/GetNext ( +see below) # 'Check Inbox for messages and exit of none found # If Inbox.Items.Count = 0 Then # Exit Sub # End If my $messages = $inbox->Messages() or return Win32::OLE->LastError +(); my $filter = $messages->Filter() or return Win32::OLE->LastError() +; $filter->{Unread} = 1; # Only unread messages $messages->Sort(); # default Sort is ASC on CdoPR_MESSAGE_DELIV +ERY_TIME return $err if $err = Win32::OLE->LastError(); #' Check each message for attachments # For Each Item In Inbox.Items for (my $msg = $messages->GetFirst(); $msg; $msg = $messages->GetN +ext()) { #' Save any attachments found # For Each Atmt In Item.Attachments my $atts = $msg->Attachments; if ($atts and my $count=$atts->Count) { # Count is O.K. for + "small" collections while ($count) { my $atmt = $atts->Item($count) or next; # There shouldn't be a path in the name, but be parano +id # ' This path must exist! Change folder name as necessary. # If Left(Atmt.FileName, 10) = "Flat_file_" Then (my $f = $atmt->Name || '') =~ s#.*[:\\/]##; next if !$f or $f !~ /^Flat_file_/; # FileName = "G:\Input\" & Atmt.FileName my $outfile = "G:\\Input\\$f"; # Beware! Backslashe +s required here! # Atmt.SaveAsFile FileName $atmt->WriteToFile($OutFile); return $err if $err = Win32::OLE->LastError; --$count; # i = i + 1 # End If # Next Atmt } } # Next Item } } # end sub
This code is untested but should work modulo typoes.
Edit: Cleaned up some incoherently on the fly renamed variables
You may comment the added lines with the "filter unread messages only" and the "sort with respect to message delivery time", if not needed.
Final remark: The code makes up a dynamic temporary MAPI profile. This feature is only available with a resonable (?!) current CDO on your machine. You should be fine, if OL 2002 or (2003) is installed on your machine :-/ (not tested otherwise).
Enjoy!
Edit: ADO?? I must have been involved in AD automation too much lately
:1,.-2s/ADO/CDO/g
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
| A reply falls below the community's threshold of quality. You may see it by logging in. |