切换到宽版
  • 8878阅读
  • 7回复

[求助]Exchange 邮件附件自动转存在一个网上目录中 [复制链接]

上一主题 下一主题
 
只看楼主 倒序阅读 0楼  发表于: 2015-08-04
我写了一个VBA小程序, 在本机Outlook上完成了这个功能:将收到邮件附件自动转存在一个目录中。
请问,如何将这个程序, 在服务器上, 自动执行?
谢谢

换一个提问的方法:
在Exchange服务器上,可以添加新的规则么? 如果可以,就可以定义一个新的规则, 将某个帐号的邮件中的附件, 自动下载, 并且转存到一个固定地址。
也就是想问问,在Exchange服务器上, 是否有使用C#. VB 的编程接口。

谢谢, 回复

分享到

只看该作者 1楼  发表于: 2015-08-05
Re:Exchange 邮件附件自动转存在一个网上目 ..
VBA不清楚,Powershell可以做到。逻辑图如下:




脚本如下:


# 以下是需要导出附件的邮箱
$MailboxName = 'monthly.reporting@<domain-name>.com'

# 以下是需要存放的服务器路径
$downloadDirectory = '\\<file-server>\monthly_reports\'

# 以下是Web服务的动态链接库路径
$dllpath = "D:\Program Files\Microsoft\Exchange Server\Web Services\1.2\Microsoft.Exchange.WebServices.dll"
[VOID][Reflection.Assembly]::LoadFile($dllpath)

# 新建web服务对象
$service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2013_SP1)

# 新建LDAP安全字符串以便可以登录目标邮箱
$windowsIdentity = [System.Security.Principal.WindowsIdentity]::GetCurrent()
$sidbind = "LDAP://<SID=" + $windowsIdentity.user.Value.ToString() + ">"
$aceuser = [ADSI]$sidbind

# 自动发现截取附件的URL
$service.AutodiscoverUrl($aceuser.mail.ToString())

# 获取收件箱的Id
$folderid = new-object  Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox,$MailboxName)
$InboxFolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$folderid)

# 发现收件箱内有附件的邮件
$Sfha = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.EmailMessageSchema]::HasAttachments, $true)
$sfCollection = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+SearchFilterCollection([Microsoft.Exchange.WebServices.Data.LogicalOperator]::And);
$sfCollection.add($Sfha)

# 获取所有满足上述条件的邮件
$view = new-object Microsoft.Exchange.WebServices.Data.ItemView(2000)
$frFolderResult = $InboxFolder.FindItems($sfCollection,$view)

# 在邮件中循环
foreach ($miMailItems in $frFolderResult.Items){

    # 装载邮件
    $miMailItems.Load()

    # 在附件中循环
    foreach($attach in $miMailItems.Attachments){

        # 装载附件
        $attach.Load()

        # 将附件保存到之前定义的服务器路径
        $fiFile = new-object System.IO.FileStream(($downloadDirectory + “\” + (Get-Date).Millisecond + "_" + $attach.Name.ToString()), [System.IO.FileMode]::Create)
        $fiFile.Write($attach.Content, 0, $attach.Content.Length)
        $fiFile.Close()
    }

    # 将处理好的邮件标记为已读
    $miMailItems.isread = $true
    $miMailItems.Update([Microsoft.Exchange.WebServices.Data.ConflictResolutionMode]::AlwaysOverwrite)

    # 删除邮件(可选)
    [VOID]$miMailItems.Move("DeletedItems")
}

然后设置计划任务每月执行一次附件的导出即可。

Exchange中文站10周年献礼。Exchange2016中文视频教程热销中:edu.exchangecn.com/course/12
只看该作者 2楼  发表于: 2015-08-05
Re:Exchange 邮件附件自动转存在一个网上目 ..
非常感谢!
只看该作者 3楼  发表于: 2015-08-06
Re:Exchange 邮件附件自动转存在一个网上目 ..
请问 flowerwaiter :

可以做成Rule么?

我尝试着, 添加新的Rule



     private void CreateManagerRule()
        {
            Outlook.ExchangeUser manager;
            Outlook.Folder managerFolder;
            Outlook.AddressEntry currentUser =
                Application.Session.CurrentUser.AddressEntry;
            if (currentUser.Type == "EX")
            {
                try
                {
                    manager = currentUser.
                        GetExchangeUser().GetExchangeUserManager();

                }
                catch
                {
                    Debug.WriteLine("Could not obtain user's manager.");
                    return;
                }
                Outlook.Rules rules;
                try
                {
                    rules = Application.Session.DefaultStore.GetRules();
                    //rules = Application.Session.Stores.;

                }
                catch
                {
                    Debug.WriteLine("Could not obtain rules collection.");
                    return;
                }
                //if (manager != null)
                if (true)
                {
                    string displayName ="" ;
                    if (manager != null)
                    {
                        displayName = manager.Name;    
                    }else{

                        displayName = "Test for me";
                    }
                    
                    Outlook.Folders folders =
                        Application.Session.GetDefaultFolder(
                        Outlook.OlDefaultFolders.olFolderInbox).Folders;
                    try
                    {
                        managerFolder =
                            folders[displayName] as Outlook.Folder;
                    }
                    catch
                    {
                        managerFolder =
                            folders.Add(displayName, Type.Missing)
                            as Outlook.Folder;
                    }
                    Outlook.Rule rule = rules.Create(displayName,
                        Outlook.OlRuleType.olRuleReceive);

                    // Rule conditions
                    // From condition
                    //rule.Conditions.From.Recipients.Add(manager.PrimarySmtpAddress);

                    rule.Conditions.From.Recipients.Add("xxxx@xxxx.xx");

                    rule.Conditions.From.Recipients.ResolveAll();
                    rule.Conditions.From.Enabled = true;


                    //rule.Conditions.HasAttachment.Class..From.Enabled = true;
                    

                    // Sent only to me
                    rule.Conditions.ToMe.Enabled = true;

                    //rule.Actions..NewItemAlert;
                    //RuleAction = $rule.Actions.NewItemAlert
                    //$RuleAction.Text = "This is a demo script"
                    //$RuleAction.Enabled = $true

                    写到这里, 不知道如何把你的代码, 加到这里了
           请指教, 谢谢!


                    // Rule exceptions
                    // Meeting invite or update
                    rule.Exceptions.MeetingInviteOrUpdate.Enabled = true;

                    // Rule actions
                    // MarkAsTask action
                    rule.Actions.MarkAsTask.MarkInterval =
                        Outlook.OlMarkInterval.olMarkToday;
                    rule.Actions.MarkAsTask.FlagTo = "Follow-up";
                    rule.Actions.MarkAsTask.Enabled = true;

                    // MoveToFolder action
                    rule.Actions.MoveToFolder.Folder = managerFolder;
                    rule.Actions.MoveToFolder.Enabled = true;
                    try
                    {
                        rules.Save(true);
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine(ex.Message);
                    }
                }
            }
        }

再次感谢你的指教!

只看该作者 4楼  发表于: 2015-08-06
回 四海为家 的帖子
四海为家:请问 flowerwaiter :
可以做成Rule么?
我尝试着, 添加新的Rule
.......?(2015-08-06 16:23)?

你缺的不过是把附件导出来的脚本,根据我的注释把对应脚本加进去就行了
Exchange中文站10周年献礼。Exchange2016中文视频教程热销中:edu.exchangecn.com/course/12
只看该作者 5楼  发表于: 2015-08-07
Re:Exchange 邮件附件自动转存在一个网上目 ..
感谢flowerwaiter的回答。

我试用了你的方法后。发现我们很多的用户没有使用 Web Outlook的权限。 只能在客户终端上Client中使用。

所以,在使用EWS:Microsoft.Exchange.WebServices.dll的时候, 那些用户就有限制了。不能调用

这几天, 我发现了2种方法

1。在Client 上, 用VB做一个Script(Save Attachments to the hard drive)。 然后,用户可以自己添加Rule + Run a Script.
但是, 有个缺点, 如果这个用户不开机, 附件就不能自动转存到一个固定地址。

2。在服务器上,用C#在VC2010下,添加一个新的Rule。 不知道是否可以自动转存附件么。

完成这个功能有些限制,不能使用EWS Tools,最好不使用 Transport service。有点郁闷。



只看该作者 6楼  发表于: 2015-08-07
Re:Exchange 邮件附件自动转存在一个网上目 ..
附上, Script in VB

Option Explicit

Sub Check_attachments_nosave(myItem As Outlook.MailItem)
    
    'Dim Response As VbMsgBoxResult
    'Response = MsgBox("Do you REALLY want to PERMANENTLY delete all attachments in all SELECTED mails?", vbExclamation + vbDefaultButton2 + vbYesNo)
    'If Response = vbNo Then Exit Sub
    
    Dim myAttachment As Attachment
    Dim myAttachments As Attachments
    Dim selItems As Selection
    Dim lngAttachmentCount As Long
    Dim strFile As String
    Dim Report As String
        
    ' Set reference to the Selection.
    Set selItems = ActiveExplorer.Selection
    
    ' Loop though each item in the selection.
    Report = ""
    
    For Each myItem In selItems
        
        Set myAttachments = myItem.Attachments
        lngAttachmentCount = myAttachments.Count
        ' Loop through attachmentsuntil attachment count = 0.
    
        While lngAttachmentCount > 0
            
            'strFile = myAttachments.Item(1).FileName & "; " & strFile
            
            strFile = "d:\temp\" + myAttachments.Item(lngAttachmentCount).FileName                  '  & "; " & strFile
                        
           ' sFileName = "d:\temp\" + CurrentAttachment.FileName
                        
            If Dir(strFile) <> "" Then
            
                Debug.Print strFile + " ist schon vorhanden."
                
            Else
            
                Debug.Print strFile
                
                myAttachments.Item(lngAttachmentCount).SaveAsFile (strFile)
                
                Report = Report & strFile & vbCrLf
                
            End If
                        
  '          myAttachments(1).Delete
            lngAttachmentCount = lngAttachmentCount - 1
            
        Wend
        
'        If myItem.BodyFormat <> olFormatHTML Then
'           myItem.Body = myItem.Body & vbCrLf & "The file(s) removed were: " & strFile
  '      Else
   '         myItem.HTMLBody = myItem.HTMLBody & "<p>" & "The file(s) removed were: " & strFile & "</p>"
    '    End If
    
      '  myItem.Save
        strFile = ""
    Next
    
    MsgBox "Done. All attachments were saved in d:\temp\", vbOKOnly, "Message"
    
    Set myAttachment = Nothing
    Set myAttachments = Nothing
    Set selItems = Nothing
    Set myItem = Nothing

End Sub




只看该作者 7楼  发表于: 2015-08-09
回 四海为家 的帖子
四海为家:附上, Script in VB
Option Explicit
Sub Check_attachments_nosave(myItem As Outlook.MailItem)
.......?(2015-08-07 21:01)?

Debug一下
Exchange中文站10周年献礼。Exchange2016中文视频教程热销中:edu.exchangecn.com/course/12
快速回复
限60 字节
 
上一个 下一个