【问题标题】:How to convert attachments to Base64如何将附件转换为 Base64
【发布时间】:2021-08-07 10:14:47
【问题描述】:

我有点不知所措,需要帮助。 我正在尝试构建一个邮件集成工具,它将检查 POP3 和 IMAP4 邮箱中的电子邮件并将它们导入另一个系统。我要导入电子邮件的系统只能将附件作为 Base64 字符串处理。

我正在使用带有 Mailozaurr (https://github.com/EvotecIT/Mailozaurr) 模块的 PowerShell 7.1,Mailozaurr 在后台使用 MailKit 和 MimeKit,以便连接到 POP3 和 IMAP4 服务器并收集/下载/收集任何电子邮件。然后,我会将电子邮件的不同属性转换为 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)"

【问题讨论】:

    标签: powershell mailkit mimekit


    【解决方案1】:

    您可能会做这样的事情(请记住,我不擅长使用 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 编码(尽管它会有需要删除的换行符),但这是一个脚本而且可能不值得把它弄得太复杂。

    【讨论】:

    • 非常非常非常感谢,这让我一路回家!但是,$filename = "$($attachment.Content.Filename)" 应该是 $filename = "$($attachment.Filename)"
    【解决方案2】:

    使用 .NET 的 Convert.ToBase64String(Byte[]) method 可以轻松将文件转换为 Base64。

    该方法需要一个字节数组作为输入,您可以通过File.ReadAllBytes()获取。请注意,此方法需要一个绝对路径才能工作。如果您在 PowerShell 中使用相对路径,请先使用 Convert-Path 将它们转换为绝对路径。

    通用方法:

    $absolutePath = Convert-Path "attachment filename"
    $bytes = [System.IO.File]::ReadAllBytes($absolutePath)
    $base64 = [Convert]::ToBase64String($bytes)
    
    Write-Host $base64
    

    【讨论】:

    • 感谢您的回答,但我不会在发送之前将附件保存到文件/磁盘。我已经用一个示例更新了我的问题,说明我如何通过读取流来解决它。
    • @Anders “如何在 .NET 中将流转换为 base64?” 在 SO 和其他地方很可能是一个已回答的问题。你找过例子吗?您需要做的就是将它们转换为 PowerShell 语法。
    猜你喜欢
    • 1970-01-01
    • 2015-04-29
    • 1970-01-01
    • 2023-01-07
    • 1970-01-01
    • 1970-01-01
    • 2021-07-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多