Powershell Unload Module ... complètement

voix
25

Je travaille sur le débogage d' un projet Powershell. J'utilise Import-Modulepour charger le module PS de mon dll C # et tout fonctionne bien. Appel Remove-Modulene déchargent complètement le module bien que la DLL est toujours verrouillé et ne peut pas être supprimé.

Y at - il un moyen d'obtenir PSH pour décharger complètement le module et libérer la DLL afin que je puisse copier et recharger à nouveau en utilisant Import-Modulesans redémarrer la console PSH?

Mise à jour
Donc , si vous chargez un module dans un AppDomain séparé , il ne fonctionne toujours comme un module normal? Quelqu'un peut -il donner un exemple?

Créé 26/08/2009 à 23:43
source utilisateur
Dans d'autres langues...                            


10 réponses

voix
20

Il existe une solution. Ouvrez une autre instance de PowerShell:

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

Après la sortie, vous serez ramené à l'instance de PowerShell à partir de laquelle vous avez fait cet appel ( en supposant que vous avez fait l' powershellappel intérieur et à l' instance de PowerShell). Vous pouvez passer dans l' un des arguments normaux à powershell, de sorte que vous pouvez utiliser -Command ou -File. Par exemple,

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.

Lorsque sort PowerShell, il libérera le verrou sur la DLL, vous permettant de continuer à travailler.

Tout cela a été fait à partir de l'interface de ligne de commande PowerShell. Je ne l' ai pas testé ce qui se passe si vous jetez powershellau milieu d'un script ou si cela fonctionne dans les ISE. (Je soupçonne que cela fonctionne dans les ISE.) Même si le cas ne fonctionne pas à l' intérieur d' un script, cela est encore utile au cours du développement.

Modifier:

Est-ce que quelques vérifications. Donc , cela semble fonctionner correctement à partir de scripts et à Ise, mais il y a une mise en garde dans les ISE. ISE, vous ne pouvez pas lire une entrée de l'utilisateur pendant que vous êtes à l' intérieur du processus de PowerShell séparé. Si vous essayez, le script ou commandes arrêtent d'attendre, mais aucune boîte d'entrée est montrée comme normale, et bien sûr, vous ne pouvez pas taper directement dans la fenêtre de sortie ISE. Donc , si vous devez demander une entrée au milieu de [do work], invite avant la cuisson une nouvelle instance de PowerShell, et le transmettre dans le travail en tant que paramètre. Ce ne sont pas des problèmes du tout si vous utilisez la ligne de commande PowerShell régulière.

Créé 09/10/2012 à 21:05
source utilisateur

voix
16

Non. Comme PowerShell utilise .NET dessous présente les mêmes exigences. Vous ne pouvez pas décharger un dll d'un AppDomain .NET sans décharger le AppDomain lui-même. Comme l'interface utilisateur vit PowerShell dans le même AppDomain cela est impossible.

Créé 26/08/2009 à 23:47
source utilisateur

voix
6

Je vois quelques réponses réalistes, mais le mien est là, dans le cas où cela est encore un problème pour quelqu'un (ce qui est assez paresseux, ce qui est agréable).

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

Longue histoire courte, la création d'un PSSession pour votre ordinateur local crée une session de Powershell différents, y compris ce qui est considéré « chargé », et lorsque vous quittez, il nettoie les choses pour vous.

Créé 09/12/2015 à 19:50
source utilisateur

voix
5

Je crois que cela est vrai pour PowerShell: dans le monde .NET la seule façon de décharger un ensemble est de le charger dans un autre AppDomain; une fois que l'ensemble est chargé dans une AppDomaindemeure chargée pendant toute la durée de ce AppDomain.


Voici un exemple d'un fil demandant à peu près la même question et montrant une deux manières de créer et de charger le module dans un nouveau AppDomain:

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

Créé 26/08/2009 à 23:47
source utilisateur

voix
3

Dans le contexte du développement Cmdlet, et avoir des problèmes avec le déchargement de votre DLL, il existe deux approches que j'utilise.

Tout d'abord, je développe dans Visual Studio, et la configuration d'un programme externe (PowerShell) pour charger mon applet de commande. De cette façon, mes module charge quand je démarre le débogage, et quand je décharge arrête le débogage.

En second lieu, à ces occasions où je sais que je veux charger un module, faire un certain travail et vérifier que le module est déchargé après, j'utilise une deuxième instance de PowerShell. Cela a été discuté dans d'autres réponses, et ma réponse ci-dessous montre comment activer ce flux de travail en utilisant une fonction avec un alias dans mon profil. Je changer l'invite pour que je puisse avoir un rappel visuel que je suis dans une « fenêtre PowerShell récursive ».

Créer un script dans votre profil pour démarrer 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

Modifier les paramètres de débogage pour votre projet Cmdlet

Démarrer le programme externe :

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

Arguments de ligne de commande :

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

Déboguer votre module

Maintenant , à partir de Visual Studio, commencez débogueur avec F5, et vous avez une nouvelle fenêtre PowerShell avec votre Cmdlet chargé, et vous pouvez le déboguer comme bon vous semble.

Utiliser l'alias « sdp » de toute fenêtre PowerShell

Étant donné que la fonction Start-DebugPowerShell est dans notre profil et nous a donné un alias sdp, vous pouvez l' utiliser pour démarrer une deuxième instance de PowerShell quand vous en avez besoin.

Créé 11/03/2016 à 01:29
source utilisateur

voix
3

J'ai eu les mêmes problèmes et a fini par envelopper la DLL que je voulais charger dans un exe que je puis commandline appelé à partir du script. De cette façon, j'évitais le chargement de la DLL dans mon application à tous.

Créé 25/01/2011 à 09:09
source utilisateur

voix
0

J'ai eu quelques modules externes ( ImportExcel je voulais) mettre à jour comme ça et ça n'a pas fonctionné . Pour cette situation Install-Module -Scope CurrentUser <MyExternalModuleName>(dans le cas où il est dans votre dossier de module utilisateurs, sinon omettez le -Scope ...param) a travaillé.

(Comment ils ont réussi en interne - Je ne sais pas, mais vous gardez votre session en cours de PS.)

Créé 03/09/2018 à 13:36
source utilisateur

voix
0

J'utilise un script simple qui renomme DLL cible et la charge en tant que module. Ici, nous avons 2 hacks:

  1. lorsque le module chargement de l'objet d'assemblage .net nous sommes module chargé avec le nom « dynamic_code_module_FirstPowershellModule »
  2. donc avant l'importation nous déchargeons ce module et de créer un nouveau fichier de renommé

ensembles précédents restent inutilisés dans le domaine

script doit être exécuté après chaque projet de reconstruction

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
Créé 17/05/2016 à 16:44
source utilisateur

voix
0

Les modules PS sont assemblées .net, quand vous Import-Module, vous les chargez dans le AppDomain de l'hôte PowerShell (l'application). Remove-Modulejuste supprime les modules de la session en cours.

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

Il n'y a aucun moyen de décharger un ensemble individuel sans décharger tous les domaines d'application qui contiennent. Utiliser la méthode de déchargement de AppDomain pour décharger les domaines d'application. Pour plus d'informations, consultez Déchargement d'un domaine d'application.

Vous pouvez commencer un nouvel hôte PowerShell dans une nouvelle AppDomain, importez votre module à l'hôte et faire le travail PowerShell. Le module est aussi normal que il a été en cours d'exécution dans votre hôte précédent. La seule différence est qu'il est dans un hôte en cours d'exécution dans un autre AppDomain.

Créé 07/05/2013 à 02:57
source utilisateur

voix
0

Faites une copie de la DLL et charger cette copie. Vous pouvez recharger DLLs.

Créé 29/01/2013 à 07:11
source utilisateur

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