你能再次删除PowerShell中的Add-ed类型吗?

iibxawm4  于 2023-04-30  发布在  Shell
关注(0)|答案(6)|浏览(117)

我目前正在用C#编写一个库,并在某些情况下使用PowerShell快速测试它。然而,这阻止了我重新构建项目,因为PowerShell显然仍然打开了DLL。
在使用Add-Type添加DLL后,是否有方法再次卸载DLL?文档似乎没有关于这一点的线索,显然的候选者是Remove-Type(它不存在--反正只有一个命令,它的名词是Type)。关闭PowerShell并执行导航到构建目录的所有操作并在每次想要重建时再次添加类型变得很麻烦。

zdwk9cvp

zdwk9cvp1#

就像其他人说的,这是一个。NET行为。无法卸载加载到AppDomain中的程序集。只能卸载AppDomain,powershell使用单个appdomain。几年前,我在博客上写过一段:
https://web.archive.org/web/20170707034334/http://www.nivot.org/blog/post/2007/12/07/WhyAppDomainsAreNotAMagicBullet
当我像这样进行测试时,我通常会打开一个shell,并使用嵌套的shell来进行测试。启动powershell,cd到绑定位置然后运行“powershell”启动嵌套shell(新进程.)“退出”重新开始,再次运行“powershell”。

9gm1akwq

9gm1akwq2#

我发现解决这个问题的最简单方法是将Add-Type和测试代码 Package 在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

测试方法的输出将回显到控制台。

aemubtdh

aemubtdh3#

如果你的程序集不需要binding context,你可以这样做:

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

pkmbmrz74#

下面是一个完整的示例,它允许将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将确保收到作业的输出,否则它将丢失。

irlmq6kh

irlmq6kh5#

我一直面临着类似的问题。不可能卸载类型/程序集(这是因为它应用于。NET框架)。
在.NET中,如果您创建一个新的应用程序域(System.AppDomain)并将程序集加载到该域中,就可以解决这个问题。可以卸载应用程序域,也可以卸载所有dll。
我还没有尝试过,因为对我来说,关闭Console中的标签并打开新的标签要简单得多。

puruo6ea

puruo6ea6#

Visual Studio代码:

设置-〉扩展-〉PowerShell配置-〉调试:创建临时集成控制台

复选框:“* 确定是否为每个调试会话创建临时PowerShell集成控制台,用于调试PowerShell类和二进制模块。* ”

相关问题