Подтвердить что ты не робот

Вы можете снова удалить добавленный тип в PowerShell?

В настоящее время я пишу библиотеку на С# и использую PowerShell для быстрого тестирования в некоторых случаях. Однако это мешает мне перестроить проект, поскольку у PowerShell, очевидно, все еще есть DLL.

Есть ли способ выгрузить DLL снова после добавления его с помощью Add-Type? Документация, похоже, не знает об этом, и очевидный кандидат будет Remove-Type (которого не существует - в любом случае есть только одна команда с Type в качестве своего существительного). Крайне сложно закрыть PowerShell и сделать все, что нужно, перейдя в каталог сборки и добавив тип снова каждый раз, когда я хочу перестроить.

4b9b3361

Ответ 1

Как говорят другие, это поведение .NET. Ассембли, загруженные в AppDomain, не могут быть выгружены. Только AppDomain может быть выгружен, а powershell использует один appdomain. Несколько раз я писал об этом несколько раз: http://www.nivot.org/2007/12/07/WhyAppDomainsAreNotAMagicBullet.aspx

Когда я тестирую это, я обычно держу оболочку открытой и использую вложенную оболочку для выполнения тестов. start powershell, cd to bin location, затем запустите "powershell", чтобы запустить вложенную оболочку (новый процесс). "Выход" для начала и снова запустить "powershell".

Ответ 2

Я считаю, что самый простой способ обойти эту проблему - обернуть 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

Результат тестового метода будет передан на консоль.

Ответ 3

Если ваша сборка не требует контекста привязки вы можете сделать это:

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

Ответ 4

Вот полный пример, который позволяет запустить команду 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 будет следить за тем, чтобы результат работы был получен, поскольку в противном случае он будет потерян.

Ответ 5

Я столкнулся с подобной проблемой. Невозможно выгрузить тип/сборку (что связано с платформой .NET).

В .NET вы можете решить эту проблему, если вы создаете новый домен приложения (System.AppDomain) и загружаете сборку в этот домен. Можно разгрузить домен приложения, и он также выгружает все DLL.

Я еще не пробовал, потому что для меня гораздо проще закрыть вкладку Console и открыть новую.