Dec
7
Written by:
Oisin Grehan
12/7/2007 6:49 PM
As knowledge of PowerShell increases for those new to .NET, there comes a point when people start to notice some shortcomings of the Assembly loading/unloading mechanisms of the 2.0 CLR. Namely, once you load an assembly into PowerShell to use it, you can't unload it again. The only way to remove it from memory is to restart PowerShell. Eventually, you might read something about how Assemblies can be loaded into AppDomains, and AppDomains themselves can be unloaded. This is true, but for the most part it is not much use in PowerShell unless the Types in question where specifically designed with this in mind. For those of you who understand enough of what I'm talking about to get this far without going "huh?", the following script will demonstrate some of the issues at hand:
Before you run this script, please disable PowerTab or any other SnapIns that may load the WinForms assembly into the current AppDomain. In short, this script creates a Form object in a child AppDomain, examines the current AppDomain for the WinForms assembly. It then attempts to manipulate the Form and again examines the current AppDomain for the WinForms assembly.
-
- $assembly = "System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
-
- function IsWinFormsLoaded() {
- $loaded = [appdomain]::currentdomain.getassemblies()
- $winforms = $loaded | ? { $_.fullname -like "system.windows*" }
- return ($winforms -ne $null)
- }
-
- if (-not (IsWinFormsLoaded)) {
- "Creating child AppDomain..."
- $child = [appdomain]::Createdomain("child",$null,$null)
-
-
- "Creating remote WinForms Form in child AppDomain... "
- $handle = $child.CreateInstance($assembly, "System.Windows.Forms.Form")
-
-
- "Returned object is a {0}" -f $handle.GetType()
- $handle | gm
-
-
- "Is Windows Forms loaded in this AppDomain? {0}" -f (IsWinFormsLoaded)
-
-
- "Unwrapping, examining methods..."
- $form = $handle.Unwrap()
- $form | gm | select -first 10
-
-
- "Is Windows Forms loaded in this AppDomain? {0}" -f (IsWinFormsLoaded)
-
- } else {
- write-warning "System.Windows.Forms is already loaded. Please disable PowerTab or other SnapIns that may load System.Windows.Forms and restart PowerShell."
- }
Hopefully this will clear up any outstanding questions. I'll post more information about this later, or possibly add to this post.
appdomains.ps1 (1.33 KB)
Tags: