web-dev-qa-db-ja.com

PowerShellで追加された型を再度削除できますか?

私は現在、C#でライブラリを作成していますが、PowerShellを使用して、いくつかの機会にすばやくテストしていました。ただし、PowerShellでDLL open。

Add-Typeで追加した後、再びDLL)をアンロードする方法はありますか?ドキュメントにはその手がかりがないようで、明らかな候補はRemove-Typeになります(これは存在しません。とにかくTypeを名詞とするコマンドは1つしかありません。)PowerShellを閉じて、ビルドディレクトリに移動してタイプを追加するたびにすべてを行うのは面倒です再構築したい。

58
Joey

他の人が言うように、これは.NETの動作です。 AppDomainにロードされたアセンブリはアンロードできません。アンロードできるのはAppDomainのみで、powershellは単一のappdomainを使用します。私は数年前にこれについて少しブログを書きました: http://www.nivot.org/2007/12/07/WhyAppDomainsAreNotAMagicBullet.aspx

このようにテストするときは、通常、シェルを開いたままにして、ネストされたシェルを使用してテストを行います。 powershellを起動し、binの場所にcdしてから、「powershell」を実行してネストされたシェル(新しいプロセス)を開始します。「exit」でやり直し、「powershell」を再度実行します。

54
x0n

この問題を回避する最も簡単な方法は、Add-Typeとテストコードを Start-Job で囲むことです。 Start-Jobはバックグラウンドプロセスを作成し、タイプがそこにロードされます。完了すると、プロセスは終了し、自由に再試行できます。

以下に例を示します。

$job = Start-Job -ScriptBlock {

    Add-Type -path 'my.dll'
    $myObj = new-object My.MyTestClassName

    $result = $myObj.TestMethod
    $result
}
Wait-Job $job
Receive-Job $job

テストメソッドからの出力はコンソールにエコーされます。

35

アセンブリが binding context を必要としない場合、これを行うことができます:

$bytes = [System.IO.File]::ReadAllBytes("Path_To_Your_Dll.dll")
[System.Reflection.Assembly]::Load($bytes)
23
George Howarth

Add-Typeコマンドをバックグラウンドジョブとして実行し、アセンブリが完了したらアンロードされるようにする完全な例を次に示します。

# Start-Job will not preserve the working directory, so do it manually
# Other arguments can also be passed to the job this way
$cd = Split-Path $MyInvocation.MyCommand.Path
$jobParams = @{
    'cd' = $cd
}

Start-Job -InputObject $jobParams -ScriptBlock {
    cd $Input.cd
    Add-Type -Path Assembly.dll
} | Receive-Job -Wait -AutoRemoveJob

Receive-Job -Waitは、ジョブの出力が確実に受信されるようにします。そうしないと、ジョブの出力が失われます。

3
Knaģis

私は同様の問題に直面しています。型/アセンブリをアンロードすることはできません(.NETフレームワークに適用されるためです)。

.NETでは、新しいアプリケーションドメインを作成すると解決できます(System.AppDomain)アセンブリをそのドメインにロードします。アプリドメインをアンロードすることもできます。これにより、すべてのdllもアンロードされます。

Console のタブを閉じて新しいタブを開く方がはるかに簡単なので、まだ試していません。

0
stej