Powershell Descarregar Módulo ... completamente

votos
25

Eu estou trabalhando em um projeto de depuração PowerShell. Eu estou usando Import-Modulepara carregar o módulo PS do meu C # dll e tudo funciona bem. Chamada Remove-Modulenão descarrega completamente o módulo embora como a DLL ainda está bloqueado e não pode ser excluído.

Existe uma maneira de obter PSH para descarregar completamente o módulo e liberar a DLL para que eu possa copiar sobre ele e recarregá-lo novamente usando Import-Modulesem reiniciar o console PSH?

Atualização
Então, se você carregar um módulo em um AppDomain separado ele ainda funciona como um módulo normal? Alguém pode dar um exemplo?

Publicado 26/08/2009 em 23:43
fonte usuário
Em outras línguas...                            


10 respostas

votos
20

Há uma solução alternativa. Abra outra instância do PowerShell:

PS > powershell
PS > [load DLL]
PS > [do work]
PS > exit

Após a saída, você será levado de volta para a instância do PowerShell, dos quais fez esta chamada (supondo que você fez a powershellchamada dentro e instância de PowerShell). Você pode passar em qualquer um dos argumentos normais para powershell, assim você pode usar -Command ou -File. Por exemplo,

PS > powershell -Command '[load DLL]; [do work]' # Executes a command and exits
PS > powershell -Command '.\myscript.ps1 param1 param2' # Executes the script and exits
PS > powershell -File .\myscript.ps1 param1 param2 # Executes a script and exits.

Quando PowerShell sai, ele vai liberar o bloqueio na DLL, o que lhe permite continuar a trabalhar.

Tudo isso foi feito a partir da interface de linha de comando PowerShell. Eu não testei o que acontece se você jogar powershellno meio de um script ou se isso funciona dentro ISE. (Eu suspeito que funciona dentro ISE.) Mesmo se não funciona dentro de um script, isso ainda é útil durante o desenvolvimento.

Editar:

Fez alguns testes. Portanto, este parece funcionar bem a partir de scripts e no ISE, mas há uma ressalva dentro ISE. De ISE, você não pode ler qualquer entrada do usuário enquanto você está dentro do processo PowerShell separado. Se você tentar, o script ou comandos de parar para esperar, mas nenhuma caixa de entrada é mostrada como normal, e, claro, você não pode digitar diretamente na janela de saída no ISE. Então, se você precisa para solicitar a entrada no meio [do work], solicitar antes de disparar uma nova instância do PowerShell, e passá-lo para o trabalho como um parâmetro. Estes não são problemas em tudo se você estiver usando a linha de comando normal PowerShell.

Respondeu 09/10/2012 em 21:05
fonte usuário

votos
16

Não. Como PowerShell usa .NET debaixo dela tem os mesmos requisitos. Você não pode descarregar um DLL de um AppDomain .NET sem descarregar o próprio AppDomain. Como a interface do usuário PowerShell mora no mesmo AppDomain isso não é possível.

Respondeu 26/08/2009 em 23:47
fonte usuário

votos
6

Eu vejo algumas respostas viáveis ​​aqui, mas aqui é meu, caso este ainda é um problema para alguém (e isso é muito preguiçoso, o que é bom).

Enter-PSSession -localcomputername
[load dlls]
[execute script(s)]
Exit-PSSession

Para encurtar a história, criando uma PSSession para o seu computador local cria uma sessão do PowerShell diferente, incluindo o que é considerado "carregado", e quando você sair, ele limpa as coisas para você.

Respondeu 09/12/2015 em 19:50
fonte usuário

votos
5

Eu acredito que isso vale para PowerShell: no mundo do .NET a única maneira de descarregar um assembly é carregá-lo em um diferente AppDomain; uma vez que um conjunto é carregado para um AppDomainque permanece carregado para o tempo de vida do que AppDomain.


Aqui está um exemplo de um tópico pedindo praticamente a mesma pergunta e mostrar algumas maneiras de criar e carregar o módulo em um novo AppDomain:

http://www.eggheadcafe.com/conversation.aspx?messageid=30789124&threadid=30766269

Respondeu 26/08/2009 em 23:47
fonte usuário

votos
3

No contexto do desenvolvimento Cmdlet, e tendo problemas com descarga sua DLL, há duas abordagens que eu uso.

Em primeiro lugar, eu desenvolver no Visual Studio, e configurar um programa externo (PowerShell) para carregar a minha Cmdlet. Desta forma, os meus módulo carrega quando eu iniciar a depuração, e descarrega quando eu parar a depuração.

Em segundo lugar, nas ocasiões em que eu sei que eu quero carregar um módulo, fazer algum trabalho, e garantir o módulo é descarregado depois, eu uso uma segunda instância do PowerShell. Isto foi discutido em outras respostas, e minha resposta abaixo mostra como habilitar este fluxo de trabalho usando uma função com um alias em meu perfil. Eu mudar o prompt para que eu possa ter um lembrete visual que estou em uma "janela PowerShell recursiva".

Criar um script no seu perfil para começar PowerShell

function Start-DebugPowerShell
{
    PowerShell -NoProfile -NoExit -Command {
        function prompt {
            $newPrompt = "$pwd.Path [DEBUG]"
            Write-Host -NoNewline -ForegroundColor Yellow $newPrompt
            return '> '
        }
    }
}
Set-Alias -Name sdp -Value Start-DebugPowerShell

Editar configurações de depuração para seu projeto Cmdlet

Iniciar programa externo :

C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe

Argumentos de linha de comando :

-NoProfile -NoExit -Command "Import-Module .\MyCoolCmdlet.dll"

Depurar o Módulo

Agora a partir do Visual Studio, iniciar depurador com F5, e você tem uma nova janela PowerShell com o Cmdlet carregado, e você pode depurar-lo como quiser.

Use o alias 'PSD' a partir de qualquer janela do PowerShell

Como a função Start-DebugPowerShell está em nosso perfil e que nos deu um alias sdp, você pode usar isso para iniciar uma segunda instância do PowerShell sempre que precisar.

Respondeu 11/03/2016 em 01:29
fonte usuário

votos
3

Eu tive os mesmos problemas e acabou envolvendo a DLL eu queria carregar dentro de um exe de linha de comando que eu então chamado a partir do script. Dessa forma eu evitava carregar a DLL dentro da minha aplicação em tudo.

Respondeu 25/01/2011 em 09:09
fonte usuário

votos
0

Eu tinha algum módulo externo ( ImportExcel ) Eu queria atualizar como este e não funcionou . Para esta situação Install-Module -Scope CurrentUser <MyExternalModuleName>(no caso, é na sua pasta módulo de usuários, caso contrário omitir o -Scope ...param) trabalhou.

(Como eles conseguiram isso internamente - eu não sei, mas você manter a sua sessão PS atual.)

Respondeu 03/09/2018 em 13:36
fonte usuário

votos
0

Eu uso um script simples que renomeia DLL alvo e carrega-lo como módulo. Aqui temos 2 hacks:

  1. quando o módulo está a ser carregado a partir de objeto de montagem .NET got carregado módulo com o nome "dynamic_code_module_FirstPowershellModule"
  2. por isso antes de importação que descarregar este módulo e criar novo a partir do arquivo renomeado

assembléias anteriores ficar sem uso no domínio

script deve ser executado depois de cada projeto de reforma

Get-Module -Name "*FirstPowershellModule*" | Remove-Module
$ii++
$destPath = "D:\Dev\FirstPowershellModule\FirstPowershellModule\bin\Debug\FirstPowershellModule" + $ii+ ".dll"
Copy-Item D:\Dev\FirstPowershellModule\FirstPowershellModule\bin\Debug\FirstPowershellModule.dll -Destination $destPath
$ass = [System.Reflection.Assembly]::LoadFile($destPath)
import-module -Assembly $ass
Respondeu 17/05/2016 em 16:44
fonte usuário

votos
0

Os módulos PS são conjuntos .net, quando você Import-Module, você carregá-los no AppDomain do PowerShell Anfitrião (a aplicação). Remove-Moduleapenas remove módulos da sessão atual.

De acordo com MSDN, http://msdn.microsoft.com/en-us/library/ms173101(v=vs.80).aspx

Não há maneira a descarregar uma montagem indivíduo sem descarregar todos os domínios de aplicação que o contenham. Use o método Unload de AppDomain para descarregar os domínios de aplicação. Para mais informações, consulte Descarregar um domínio de aplicação.

Você poderia começar um novo hospedeiro PowerShell em um novo AppDomain, importar o módulo para o anfitrião e fazer o trabalho PowerShell. O módulo é tão normal como ele estava correndo em seu hospedeiro anterior. A única diferença é que ele está em um host executando em um AppDomain diferente.

Respondeu 07/05/2013 em 02:57
fonte usuário

votos
0

Faça uma cópia da DLL e carregar essa cópia. Você pode Atualizar DLLs.

Respondeu 29/01/2013 em 07:11
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more