Tuesday, August 9, 2011

Powershell locks loaded assemblies. Remove-Module doesn't help.

I was testing an assembly generated by Visual Studio. I imported the module into powershell via Import-Module, created the class I wanted, invoked its members, and viewed the results. Then I tweaked the project in Visual Studio and rebuilt. Powershell had the output assembly loaded and locked, so the build failed.

No news there.

The first workaround was to just close powershell and reopen it.

But! I figured I could call Remove-Module and get passed the lock without actually closing Powershell...
While this seemed like a good idea. It failed. Powershell didn't remove the lock it had on the imported assembly and it was still listed in the modules that Powershell was using. Remove-Module didn't remove the module. It just stopped showing up in Get-Modules. In fact, the variables created using the .net dll were still alive in the powershell process. Remove-Module was no solution.

Next! I figured that I would load the module inside of a powershell session and then unload the session.
Enable-PSRemoting
$session = $New-PSSession
Enter-PSSession $session
#Do Stuff
Exit-PSSession
Remove-PSSession $session

This failed as well. :(

Next I figured that I could create an AppDomain, create a Runspace in the AppDomain, do stuff, and then unload the AppDomain. I'm certain that this approach would work, but it isn't worth the time, especially since the following pseudo-shadow copy solution will work just fine:

$fileName = [System.IO.Path]::GetTempFileName()
[Environment]::CurrentDirectory = "myProjectDirectory\bin\x86\Debug"
[System.IO.File]::Copy("MyDll.dll", $fileName + ".dll")
Import-Module ($filename + ".dll")

And thus the module is loaded, and doesn't lock the Visual Studio output files.

1 comment:

  1. This is great! Ran into similar issues and the exact same line of reasoning in using Remove-Module to try and unlock it.

    ReplyDelete