2021-10-16

PowerShellでJISコードのメールを送信する (MailKit編) (1)

SmtpClient編 に続きMailKit編です。

パッケージの確認

https://www.nuget.org/ にアクセスしてMailKitを検索します。
名前・バージョン・Dependenciesを確認して、依存パッケージを辿ります。
MailKit -> MimeKit -> Portable.BouncyCastleの順で依存関係があることが分かります。

MailKit のインストール

PowerShellを管理者モードで起動し、各パッケージをインストールします。

PS > Install-Package -Name Portable.BouncyCastle -Source https://www.nuget.org/api/v2

The package(s) come(s) from a package source that is not marked as trusted.
Are you sure you want to install software from 'https://www.nuget.org/api/v2'?
[Y] はい(Y)  [A] すべて続行(A)  [N] いいえ(N)  [L] すべて無視(L)  [S] 中断(S)  [?] ヘルプ (既定値は "N"): Y

Name                           Version          Source                           Summary
----                           -------          ------                           -------
Portable.BouncyCastle          1.8.10           https://www.nuget.org/api/v2     BouncyCastle portable version with ...


PS > Install-Package -Name MimeKit -Source https://www.nuget.org/api/v2                              
The package(s) come(s) from a package source that is not marked as trusted.
Are you sure you want to install software from 'https://www.nuget.org/api/v2'?
[Y] はい(Y)  [A] すべて続行(A)  [N] いいえ(N)  [L] すべて無視(L)  [S] 中断(S)  [?] ヘルプ (既定値は "N"): Y
Install-Package : Dependency loop detected for package 'MimeKit'.
発生場所 行:1 文字:1
+ Install-Package -Name MimeKit -Source https://www.nuget.org/api/v2
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : Deadlock detected: (MimeKit:String) [Install-Package]、Exception
    + FullyQualifiedErrorId : DependencyLoopDetected,Microsoft.PowerShell.PackageManagement.Cmdlets.InstallPackage
PS > Install-Package -Name MimeKit -Source https://www.nuget.org/api/v2 -SkipDependencies

The package(s) come(s) from a package source that is not marked as trusted.
Are you sure you want to install software from 'https://www.nuget.org/api/v2'?
[Y] はい(Y)  [A] すべて続行(A)  [N] いいえ(N)  [L] すべて無視(L)  [S] 中断(S)  [?] ヘルプ (既定値は "N"): Y

Name                           Version          Source                           Summary
----                           -------          ------                           -------
MimeKit                        2.15.1           https://www.nuget.org/api/v2     An Open Source library for creating...


PS > Install-Package -Name MailKit -Source https://www.nuget.org/api/v2

The package(s) come(s) from a package source that is not marked as trusted.
Are you sure you want to install software from 'https://www.nuget.org/api/v2'?
[Y] はい(Y)  [A] すべて続行(A)  [N] いいえ(N)  [L] すべて無視(L)  [S] 中断(S)  [?] ヘルプ (既定値は "N"): Y

Name                           Version          Source                           Summary
----                           -------          ------                           -------
MailKit                        2.15.0           https://www.nuget.org/api/v2     An Open Source .NET mail-client lib
...

Dependency loop detected について

Dependency loop detected というエラーが出たら、-SkipDependencies オプションを付けて実行します。
https://github.com/OneGet/oneget/issues/475 にあるとおり、現行の OneGetInstall-Package は単純な依存関係でないとエラーが出るようです。PackageManagementがOneGetではなくなるPowerShellGet v3で解消するようですが、現在はベータ版ということもあり確認しておりません。
なお、現在の私のInstall-Package コマンドレットのモジュールとバージョンは以下のとおりです。

PS > Get-Command -Name Install-Package | Select-Object -Property ModuleName

ModuleName
----------
PackageManagement


PS > Get-InstalledModule PackageManagement

Version    Name                                Repository           Description
-------    ----                                ----------           -----------
1.4.7      PackageManagement                   PSGallery            PackageManagement (a.k.a. OneGet) is a new way t...

アセンブリの読み込み

ダウンロードしてアセンブリを読み込んでみます。ダウンロードしたパッケージは -Destination を指定していなければ "C:\Program Files\PackageManagement\NuGet\Packages\” にあります。
Add-Type コマンドレットでMailKit.dllを読み込んでみます。

PS > Add-Type -Path "C:\Program Files\PackageManagement\NuGet\Packages\MailKit.2.15.0\lib\net45\MailKit.dll"
Add-Type : 要求された型のうち 1 つまたは複数を読み込めませんでした。詳細については、LoaderExceptions プロパティを取得してください。
発生場所 行:1 文字:1
+ Add-Type -Path "C:\Program Files\PackageManagement\NuGet\Packages\Mai ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Add-Type], ReflectionTypeLoadException
    + FullyQualifiedErrorId : System.Reflection.ReflectionTypeLoadException,Microsoft.PowerShell.Commands.AddTypeCommand

エラーが発生しました。

LoaderExceptions プロパティを取得してください。

とのことですので、try-catchブロックで囲んで実行します。

try
{
	Add-Type -Path "C:\Program Files\PackageManagement\NuGet\Packages\MailKit.2.15.0\lib\net45\MailKit.dll"
}
catch [System.Reflection.ReflectionTypeLoadException]
{
	Write-Host  "Message: $($_.Exception.Message)"
	Write-Host  "StackTrace: $($_.Exception.StackTrace)"
	Write-Host  "LoaderExceptions: $($_.Exception.LoaderExceptions)"
}
Message: 要求された型のうち 1 つまたは複数を読み込めませんでした。詳細については、LoaderExceptions プロパティを取得してください。
StackTrace:    場所 System.Reflection.RuntimeModule.GetTypes(RuntimeModule module)
   場所 System.Reflection.Assembly.GetTypes()
   場所 Microsoft.PowerShell.Commands.AddTypeCommand.LoadAssemblyFromPathOrName(List`1 generatedTypes)
   場所 Microsoft.PowerShell.Commands.AddTypeCommand.EndProcessing()
   場所 System.Management.Automation.CommandProcessorBase.Complete()
LoaderExceptions: System.IO.FileNotFoundException: ファイルまたはアセンブリ 'MimeKit, Version=2.15.0.0, Culture=neutral, PublicKeyToken=bede1c8a46c66814'、またはその 
依存関係の 1 つが読み込めませんでした。指定されたファイルが見つかりません。
ファイル名 'MimeKit, Version=2.15.0.0, Culture=neutral, PublicKeyToken=bede1c8a46c66814' です。'MimeKit, Version=2.15.0.0, Culture=neutral, PublicKeyToken=bede1c8a46c66814'

依存関係にあるMimeKitを先に読み込む必要があることが分かります。
したがって、

Add-Type -Path "C:\Program Files\PackageManagement\NuGet\Packages\Portable.BouncyCastle.1.8.10\lib\net40\BouncyCastle.Crypto.dll"
Add-Type -Path "C:\Program Files\PackageManagement\NuGet\Packages\MimeKit.2.15.1\lib\net45\MimeKit.dll"
Add-Type -Path "C:\Program Files\PackageManagement\NuGet\Packages\MailKit.2.15.0\lib\net45\MailKit.dll"

の順にするとエラーなく各アセンブリを読み込むことができます。
なお、以下のようにAdd-Type の代わりに .NET Framework のLoadFileメソッドを使うこともできます。その場合は依存関係によるエラーは出ません。

[System.Reflection.Assembly]::LoadFile("C:\Program Files\PackageManagement\NuGet\Packages\MailKit.2.15.0\lib\net45\MailKit.dll")

次回実装編に続く。

No comments:

Post a Comment