如何将附件转换为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 编码的(尽管它会有需要删除的换行符),但这是一个脚本,可能不值得让它过于复杂。