Можете ли вы снова удалить добавленный тип в PowerShell? - PullRequest
58 голосов
/ 30 июля 2010

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

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

Ответы [ 5 ]

53 голосов
/ 30 июля 2010

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

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

35 голосов
/ 30 июля 2010

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

Вывод метода тестирования будет отображен на консоли.

23 голосов
/ 30 июля 2010

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

$bytes = [System.IO.File]::ReadAllBytes("Path_To_Your_Dll.dll")
[System.Reflection.Assembly]::Load($bytes)
3 голосов
/ 10 января 2017

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

0 голосов
/ 30 июля 2010

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...