Pouvez-vous supprimer un type Add-ed dans PowerShell à nouveau?
j'écris actuellement une bibliothèque en C# et j'utilisais PowerShell pour la tester rapidement à certaines occasions. Cependant, cela m'empêche de reconstruire le projet car PowerShell a évidemment toujours la DLL ouverte.
y a-t-il un moyen de décharger la DLL à nouveau après l'avoir ajoutée avec Add-Type
? La documentation ne semble pas avoir d'indices à ce sujet et le candidat évident serait Remove-Type
(qui n'existe pas – il n'y a qu'une seule commande de toute façon avec Type
comme son nom). Il devient encombrant de fermer PowerShell et de faire tout le truc de naviguer dans le répertoire de compilation et d'ajouter le type de nouveau à chaque fois que je veux reconstruire.
5 réponses
comme disent les autres, c'est un comportement .NET. Les assemblages chargés dans un AppDomain ne peuvent pas être déchargés. Seul L'AppDomain peut être déchargé, et powershell utilise un seul appdomain. J'ai blogué sur ce sujet il y a quelques années: http://www.nivot.org/2007/12/07/WhyAppDomainsAreNotAMagicBullet.aspx
quand je teste comme ceci, je garde habituellement une coquille ouverte et utilise une coquille emboîtée pour faire des tests. démarrer powershell, cd à l'emplacement bin puis lancer "powershell" pour démarrer le shell imbriqué (nouveau processus.) "exit" pour recommencer, et exécuter "powershell".
je trouve que la façon la plus simple de contourner ce problème est d'envelopper le Add-Type
et le code de test à l'intérieur d'un Start-Job
. Start-Job
va créer un processus de fond, et le type y sera chargé. Une fois que vous avez terminé, le processus disparaît et vous êtes libre de réessayer.
voici un exemple de comment il regarde:
$job = Start-Job -ScriptBlock {
Add-Type -path 'my.dll'
$myObj = new-object My.MyTestClassName
$result = $myObj.TestMethod
$result
}
Wait-Job $job
Receive-Job $job
la sortie de La méthode d'essai sera repris à la console.
si votre assemblage ne nécessite pas un contexte de liaison vous pouvez faire ceci:
$bytes = [System.IO.File]::ReadAllBytes("Path_To_Your_Dll.dll")
[System.Reflection.Assembly]::Load($bytes)
voici un exemple complet qui permet d'exécuter la commande Add-Type
comme tâche de fond pour que l'assemblage soit déchargé une fois qu'il est terminé:
# 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
assurez-vous que la sortie de l'emploi est reçu car sinon il sera perdu.
j'ai été confronté à un problème similaire. Il n'est pas possible de décharger un type/assemblage (c'est parce qu'il s'applique à .net framework).
dans .NET, vous pouvez le résoudre si vous créez un nouveau domaine d'application ( System.AppDomain
) et chargez l'assemblage dans ce domaine. Il est possible de décharger le domaine app et cela déchargera aussi tous les dlls.
Je ne l'ai pas encore essayé, parce que pour moi il est beaucoup plus simple de fermer un onglet dans la Console et d'ouvrir une nouvelle.