如何将附件转换为Base64
How to convert attachments to Base64
我有点不知所措,需要帮助。
我正在尝试构建一个邮件集成工具,它将检查 POP3 和 IMAP4 邮箱中的电子邮件并将它们导入另一个系统。我要将电子邮件导入到的系统只能将附件处理为 Base64 字符串。
我正在使用带有模块 Mailozaurr (https://github.com/EvotecIT/Mailozaurr) 的 PowerShell 7.1,Mailozaurr 在后台使用 MailKit 和 MimeKit,以便连接到 POP3 和 IMAP4 服务器以及 gather/download/collect 任何电子邮件。然后,我会将电子邮件的不同属性转换为 XML 对象,并将其发送到系统 Web api。将电子邮件转换为 XML 对象时,需要将电子邮件中的任何附件添加到 XML 对象中:
<Attachment name="filename">base64string</sch:Attachment>
我的代码现在看起来像这样用于收集电子邮件并枚举其属性。
$pop3BasicConnParams = @{
Server = "$($configuration.host)"
Password = "$($configuration.password)"
UserName = "$($configuration.login)"
Port = $port
}
$Client = Connect-POP @pop3BasicConnParams -Options Auto
$emailItems = Get-POPMessage -Client $Client -Index 0 -Count 1
foreach ($email in $emailItems) {
$emailProperties = @{}
$emailProperties.Add("to","$($email.to.Address)")
$emailProperties.Add("from","$($email.from.Address)")
$emailProperties.Add("subject","$($email.subject)")
$emailProperties.Add("body_plain","$($email.TextBody)")
foreach ($attachment in $email.Attachments) {
if ($attachment.IsAttachment -eq 'True') {
# code to convert attachment to base64 string
$attachmentStream = $attachment.Content.Stream
$bytes = [System.IO.StreamReader]::new($attachmentStream)
$B64String = [System.Convert]::ToBase64String($bytes)
$filename = "$($attachment.Content.Filename)"
$emailProperties.Add("$filename","$base64string")
$attachment.Content.Stream.Flush()
$attachment.Content.Stream.Dispose()
}
}
}
Disconnect-POP3 -Client $Client
由于我对 MailKit、MimeKit 或 .Net 没有任何知识或经验,所以我不知道如何将附件转换为 base64 字符串(用什么替换“# code to convert attachment to base64 string”)。我可以帮忙吗?
提前致谢,安德斯。
-- 更新--
这个:$filename = "$($attachment.Content.Filename)"
应该是:$filename = "$($attachment.Filename)"
使用 .NET 将文件转换为 Base64 很容易 Convert.ToBase64String(Byte[])
method。
该方法需要一个字节数组作为输入,您可以通过File.ReadAllBytes()
获取。请注意,此方法需要绝对路径才能工作。如果您在 PowerShell 中使用相对路径,请先使用 Convert-Path
将它们转换为绝对路径。
通用方法:
$absolutePath = Convert-Path "attachment filename"
$bytes = [System.IO.File]::ReadAllBytes($absolutePath)
$base64 = [Convert]::ToBase64String($bytes)
Write-Host $base64
你可能会做这样的事情(请记住我不擅长 Powershell 脚本,所以语法可能不正确):
# code to convert attachment to base64 string:
# Step 1: decode the content into a memory stream (so we can get the raw bytes)
$contentStream = [System.IO.MemoryStream]::new()
$attachment.Content.DecodeTo($contentStream)
# Step 2: Get the raw content in byte array form
$bytes = $contentStream.ToArray()
# Step 3: dispose the memory stream because we don't need it anymore
$contentStream.Dispose()
# Step 4: convert the raw attachment content into a base64 string
$b64String = [System.Convert]::ToBase64String($bytes)
$filename = "$($attachment.Filename)"
$emailProperties.Add("$filename","$b64string")
可能还值得一提的是,您不需要周围的 if ($attachment.IsAttachment -eq 'True') {
,因为 $email.Attachments
列表已经仅限于 IsAttachment 为 true 的项目。
有一些方法可以对此进行更多优化,因为 可能 内容已经是 base64 编码的(尽管它会有需要删除的换行符),但这是一个脚本,可能不值得让它过于复杂。
我有点不知所措,需要帮助。 我正在尝试构建一个邮件集成工具,它将检查 POP3 和 IMAP4 邮箱中的电子邮件并将它们导入另一个系统。我要将电子邮件导入到的系统只能将附件处理为 Base64 字符串。
我正在使用带有模块 Mailozaurr (https://github.com/EvotecIT/Mailozaurr) 的 PowerShell 7.1,Mailozaurr 在后台使用 MailKit 和 MimeKit,以便连接到 POP3 和 IMAP4 服务器以及 gather/download/collect 任何电子邮件。然后,我会将电子邮件的不同属性转换为 XML 对象,并将其发送到系统 Web api。将电子邮件转换为 XML 对象时,需要将电子邮件中的任何附件添加到 XML 对象中:
<Attachment name="filename">base64string</sch:Attachment>
我的代码现在看起来像这样用于收集电子邮件并枚举其属性。
$pop3BasicConnParams = @{
Server = "$($configuration.host)"
Password = "$($configuration.password)"
UserName = "$($configuration.login)"
Port = $port
}
$Client = Connect-POP @pop3BasicConnParams -Options Auto
$emailItems = Get-POPMessage -Client $Client -Index 0 -Count 1
foreach ($email in $emailItems) {
$emailProperties = @{}
$emailProperties.Add("to","$($email.to.Address)")
$emailProperties.Add("from","$($email.from.Address)")
$emailProperties.Add("subject","$($email.subject)")
$emailProperties.Add("body_plain","$($email.TextBody)")
foreach ($attachment in $email.Attachments) {
if ($attachment.IsAttachment -eq 'True') {
# code to convert attachment to base64 string
$attachmentStream = $attachment.Content.Stream
$bytes = [System.IO.StreamReader]::new($attachmentStream)
$B64String = [System.Convert]::ToBase64String($bytes)
$filename = "$($attachment.Content.Filename)"
$emailProperties.Add("$filename","$base64string")
$attachment.Content.Stream.Flush()
$attachment.Content.Stream.Dispose()
}
}
}
Disconnect-POP3 -Client $Client
由于我对 MailKit、MimeKit 或 .Net 没有任何知识或经验,所以我不知道如何将附件转换为 base64 字符串(用什么替换“# code to convert attachment to base64 string”)。我可以帮忙吗?
提前致谢,安德斯。
-- 更新--
这个:$filename = "$($attachment.Content.Filename)"
应该是:$filename = "$($attachment.Filename)"
使用 .NET 将文件转换为 Base64 很容易 Convert.ToBase64String(Byte[])
method。
该方法需要一个字节数组作为输入,您可以通过File.ReadAllBytes()
获取。请注意,此方法需要绝对路径才能工作。如果您在 PowerShell 中使用相对路径,请先使用 Convert-Path
将它们转换为绝对路径。
通用方法:
$absolutePath = Convert-Path "attachment filename"
$bytes = [System.IO.File]::ReadAllBytes($absolutePath)
$base64 = [Convert]::ToBase64String($bytes)
Write-Host $base64
你可能会做这样的事情(请记住我不擅长 Powershell 脚本,所以语法可能不正确):
# code to convert attachment to base64 string:
# Step 1: decode the content into a memory stream (so we can get the raw bytes)
$contentStream = [System.IO.MemoryStream]::new()
$attachment.Content.DecodeTo($contentStream)
# Step 2: Get the raw content in byte array form
$bytes = $contentStream.ToArray()
# Step 3: dispose the memory stream because we don't need it anymore
$contentStream.Dispose()
# Step 4: convert the raw attachment content into a base64 string
$b64String = [System.Convert]::ToBase64String($bytes)
$filename = "$($attachment.Filename)"
$emailProperties.Add("$filename","$b64string")
可能还值得一提的是,您不需要周围的 if ($attachment.IsAttachment -eq 'True') {
,因为 $email.Attachments
列表已经仅限于 IsAttachment 为 true 的项目。
有一些方法可以对此进行更多优化,因为 可能 内容已经是 base64 编码的(尽管它会有需要删除的换行符),但这是一个脚本,可能不值得让它过于复杂。