Dll 能否再次删除PowerShell中的添加类型?

Dll 能否再次删除PowerShell中的添加类型?,dll,powershell,add-type,Dll,Powershell,Add Type,我目前正在用C#编写一个库,并在某些情况下使用PowerShell快速测试它。但是,这阻止了我重新构建项目,因为PowerShell显然仍然打开了DLL 使用Add Type添加DLL后,是否有方法再次卸载DLL?文档中似乎没有这方面的线索,最明显的候选者是Remove Type(这是不存在的–反正只有一个命令以Type作为其名词)。每次我想要重建时,关闭PowerShell并执行导航到生成目录并再次添加类型的所有操作都会变得很麻烦。我一直面临类似的问题。无法卸载类型/程序集(因为它适用于.NE

我目前正在用C#编写一个库,并在某些情况下使用PowerShell快速测试它。但是,这阻止了我重新构建项目,因为PowerShell显然仍然打开了DLL


使用
Add Type
添加DLL后,是否有方法再次卸载DLL?文档中似乎没有这方面的线索,最明显的候选者是
Remove Type
(这是不存在的–反正只有一个命令以
Type
作为其名词)。每次我想要重建时,关闭PowerShell并执行导航到生成目录并再次添加类型的所有操作都会变得很麻烦。

我一直面临类似的问题。无法卸载类型/程序集(因为它适用于.NET framework)

在.NET中,如果装入一个新的应用程序域(
System.AppDomain
),并将程序集加载到该域中,则可以解决此问题。可以卸载应用程序域,也可以卸载所有DLL


我还没有尝试过,因为对我来说,在中关闭一个选项卡并打开一个新选项卡要简单得多。

如果您的程序集不需要

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

正如其他人所说,这是一种.NET行为。无法卸载加载到AppDomain的程序集。只能卸载AppDomain,powershell使用单个AppDomain。几年前我在博客上写过一点:


当我这样测试时,我通常会打开一个shell,并使用一个嵌套的shell进行测试。启动powershell,cd到存储箱位置,然后运行“powershell”启动嵌套的shell(新进程)。“exit”重新启动,然后再次运行“powershell”。

我发现解决此问题的最简单方法是将
添加类型和测试代码包装到存储箱中<代码>开始作业
将创建一个后台进程,并在那里加载类型。完成后,该过程将消失,您可以自由重试

下面是它的外观示例:

$job = Start-Job -ScriptBlock {

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

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

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

下面是一个完整的示例,它允许将
添加类型
命令作为后台作业运行,以便在完成后卸载程序集:

# 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
将确保作业的输出已被接收,否则它将丢失。

有一个简单的解决方法解决此问题。只要在类名中添加随机后缀,就可以了

$id = get-random
$code = @"
using System;
namespace HelloWorld    {
    public class Program$id
{
    public static void Main(){
        Console.WriteLine("Hello world!");
    }
}
}"@

Add-Type -TypeDefinition $code -Language CSharp 
iex "[HelloWorld.Program$id]::Main()"

(来自:使用PowerShell脚本执行C#代码–随机IT工具)

以及这将如何使卸载程序集成为可能?您将无法卸载,但由于读取与加载无关,因此DLL将不会保持打开和锁定(
ReadAllBytes
不会保持文件打开或锁定)。所以这取决于OP想要什么;这将解决“我无法构建”的问题,这似乎是想要卸载的驱动程序。这很好。一个小的差异/缺点是,Add Type似乎加载了指示程序集中的类型及其所有依赖项,而这只加载了指示程序集中的类型。因此,如果您需要来自上游程序集的类型,您也需要使用它来加载它们。这非常有用!甚至对于DLL,我也将其下载到内存中。不需要先将它们保存为文件。非常感谢您的共享。Powershell只使用一个appdomain,创建一个新的appdomain,将类型加载到该appdomain,然后卸载appdomain不会卸载该类型。我喜欢这种方法,不过我需要在后台作业中设置变量的结果。如果不将其写入文件,我不确定如何获取这些信息。不过,我认为这值得一试+1@SlogmeisterExtraordinaire在作业中,响应结果。在主脚本中,调用
Receive Job
来获取它。我添加了一个如何执行此操作的示例。示例中的任何打字错误都是我自己的,而不是@Start Automating的。谢谢。这确实帮助了我处理混乱的加载程序集:@jpaugh不幸的是,我的托管公司删除了我的免费帐户,我忘记了导出我的博客数据。我已经更新了到archive.org的链接。很抱歉听到这个消息!我可以说没有删除我的免费帐户;在几年的不活动之后,我又重新开始了。YMMV,但我推荐它。编辑:URL文档现在这样说:“您不能卸载或更改类型。”请参阅