如果您能够使用shell,outlook.exe可以直接运行eml文件而无需进行转换,方法如下:
outlook.exe /eml "path\to\file.eml"
即使邮件是可编辑的(X-Unsent= 1
),这个方法也能奏效。
甚至可能有一种不使用 shell 的等效方式,这将非常好。
或者你可以通过编程实现这个功能,但需要进行转换;实际上,如果你想要任何可编辑的电子邮件自动插入用户签名(因为那将是一个oft而不是msg/eml),你必须这样做。
下面我有一个powershell脚本,它接受一个eml文件,有条件地保存一个msg或oft文件,并打开它。
你可以只进行转换而不打开,或者只打开而不进行转换(但你仍然需要创建临时文件:OOM不接受从内存中创建MailItem
);我只是涵盖了所有情况以备后人所需。
我用它来关联电子邮件文件(.eml)扩展名使其在客户端机器上用该脚本打开,他们双击一个eml文件,就会在Outlook中打开。
尽管它是PowerShell,但C#非常通用;我的意思是我只阅读了C#的示例和文档(也许还有一些旧版CDO的vbs),就编写了它。
我不懂C#,我觉得把这个放在这里会对看到这篇文章的人更有帮助(因为我不得不在互联网上搜索并从头开始做)。
如果有人移植它,我很乐意接受任何编辑。
$location = $PSScriptRoot
Start-Transcript "$location\LOG.txt" -Append
. {
'MIME-Version: 1.0'
Get-Content $args[0]
} $args[0] | Set-Content "$location\tmp"
$eml = New-Object -ComObject ADODB.Stream
$eml.Open()
$eml.LoadFromFile("$location\tmp")
$eml.Flush()
$email = New-Object -ComObject "CDO.Message"
$email.DataSource.OpenObject($eml, "_Stream")
$email.DataSource.Save()
$eml.Close()
$outlook = New-Object -ComObject Outlook.Application
$output = $outlook.CreateItem(0)
$output.Sender = $email.From
$output.To = $email.To
$output.CC = $email.CC
$output.BCC = $email.BCC
$output.Subject = $email.Subject
if ($email.ReplyTo) {
$output.ReplyRecipients.Add($email.ReplyTo) | Out-Null
}
$output.BodyFormat = 2
$output.HTMLBody = $email.HTMLBody
. {for ($part = $email.HTMLBodyPart; $part = $part.Parent) {
$part.BodyParts | Where-Object {
$_.Fields('urn:schemas:httpmail:content-disposition-type').Value -match '^(inline|attachment)$'
}
}} | %{
$name = ($_.FileName -replace '^.*[/\\]','').trim('.')
if (!$name) {
$name = (
'Untitiled attachment' +
($_.Fields('urn:schemas:httpmail:content-media-type').Value `
-replace '[/\\]' ,'.' `
-replace '^\.+|\.+$','' `
-replace '^(.)' ,' $1'
)
)
}
$_.
GetDecodedContentStream().
SaveToFile("$location\$name", 2)
if ($_.Charset -imatch 'UTF-8') {
Get-Content "$location\$name" | Out-File 'tmp' -encoding utf8
Move-Item 'tmp' "$location\$name" -Force
}
$attachment = $output.Attachments.Add("$location\$name").PropertyAccessor
Remove-Item "$location\$name"
if ($_.Fields('urn:schemas:mailheader:content-id').Value) {
$attachment.SetProperty(
'http://schemas.microsoft.com/mapi/proptag/0x3712001F',
$_.Fields('urn:schemas:mailheader:content-id').Value.trim('<>')
)
}
if ($_.Fields('urn:schemas:httpmail:content-media-type').Value) {
$attachment.SetProperty(
'http://schemas.microsoft.com/mapi/proptag/0x370E001F',
$_.Fields('urn:schemas:httpmail:content-media-type').Value
)
}
}
if ($email.Fields('urn:schemas:mailheader:X-Unsent').Value -eq '1') {
$output.SaveAs("email.oft", 2)
$output.Close(1)
$outlook.CreateItemFromTemplate("email.oft").Display()
}
else {
$output.SaveAs("email.msg", 3)
$output.Close(1)
$outlook.Session.OpenSharedItem("email.msg").Display()
}
Remove-Item "$location\tmp"
我认为我已经涵盖了所有内容。这适用于附件、嵌入式图像和 CSS,但假定电子邮件是 HTML 格式且附件是 utf8 文本。
这就是我所需要的,虽然添加其他支持并不难,但如果您是私人用户或可以使用付费第三方服务,Dmitry 似乎已经通过 Redemption 做了一件非常全面的事情(我最近的旅行中经常看到他的头像),对您来说会更简单。