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
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.