2021-10-08

PowerShellでJISコードのメールを送信する (SmtpClient編[obsoleted])

こちらにあるとおり

ℹ 重要
SmtpClientは多くの最新プロトコルをサポートしていないため、新規開発にSmtpClientクラスを使用することはお勧めしません。代わりにMailKitや他のライブラリを使用してください。詳細については、GitHubのSmtpClient shouldn’t be usedをご覧ください。

SmtpClientクラスは廃止(obsolete)となりました。

後継のMailkitを使用したバージョンはこちらです。


ここでは、SmtpClientクラスを使って

を参考にPowerShellでJISコード(ISO-2022-JP)でメールを送信するコードを書いてみます。

  • 元のコードからSMTP認証あり、添付ファイルありに変更しています。
  • 一般的なメールソフトと同様、宛先、CC、件名、本文、添付ファイルを引数にした関数にしています。
  • 宛先、CC、添付ファイルについては複数項目を受け付けるため配列を引数にしています。簡略化のため、宛先とCCの Display Name はなしにしています。
function EncodeBase64([string]$str, [Text.Encoding]$enc) {
    if (!$str) {
        return $null
    }
    $base64str = [Convert]::ToBase64String($enc.GetBytes($str))
    Return [string]::Format("=?{0}?B?{1}?=", $enc.BodyName, $base64str)
}

function Send-JisMail {
    param (
        [string[]]$toArray,
        [string[]]$ccArray,
        [string]$subject,
        [string]$body,
        [string[]]$fileArray
    ) 
    # If you don't want to use arrays as arguments
    # $toArray = $to.Replace(" ","").Split(",")
 
    $fromAddress = "sender@foo.com"
    ## If you dont't need display nama, set empty
    $fromName = ""
    # 送信サーバ設定
    $server = "smtp@foo.com"
    $port = "587"
    $user = "user"
    $password = "password"
    
    $client = New-Object Net.Mail.SmtpClient($server, $port)
    $client.Credentials = New-Object Net.NetworkCredential($user, $password)
    
    $message = New-Object Net.Mail.MailMessage
    $jis = [Text.Encoding]::GetEncoding("iso-2022-jp")
    
    # 送信元
    $from = New-Object Net.Mail.MailAddress($fromAddress, $fromName)
    $message.From = New-Object Net.Mail.MailAddress($from)
    # 送信先
    foreach ($to in $toArray) {
        $message.To.Add($to)
    }
    # CC
    foreach ($cc in $ccArray) {
        $message.CC.Add($cc)
    }
    # 件名
    #$message.Subject = EncodeBase64 $subject $jis
    # for .NET Framework 4.5
    $message.Subject = EncodeBase64 (EncodeBase64 $subject $jis) $jis
    
    # 本文
    $view = [Net.Mail.AlternateView]::CreateAlternateViewFromString($body, $jis, [Net.Mime.MediaTypeNames]::Text.Plain)
    $view.TransferEncoding = [Net.Mime.TransferEncoding]::SevenBit
    $message.AlternateViews.Add($view)
    
    # 添付ファイル
    foreach ($file in $fileArray) {
        $attachment = New-Object Net.Mail.Attachment($file)
        $message.Attachments.Add($attachment)    
    }
    
    $client.Send($message)
    $message.Dispose()
}

使い方

関数を呼び出す際はSplattingを使うと分かりやすいと思います。

$args = @{
toArray = @("recipient1@bar.com","recipient2@bar.com")
subject = "件名"
body = @"
こんにちは。
これは本文です。
"@
fileArray = @("C:\Temp\新しいテキスト ドキュメント.txt")
}
Send-JisMail @args

.NET Framework 4.5 の System.Net.Mail は、エンコードした件名をデコードしてしまう(base64を指定してもQuoted-printableになる)とのことです。
そのため、上記のコードでは二重にエンコードしています。

No comments:

Post a Comment