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


In reply to Re: How do I convert VBA script to Perl? - Using Win32::OLE by pKai
in thread How do I convert VBA script to Perl? - Using Win32::OLE by Win

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.