qshinoの日記

Powershell関係と徒然なこと

AppDomain再び

AppDomain再び

PowerShellによるAppDomain制御。

ちょっと古い記事。10年前のもの。

by oising 2007/12/07 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.

# full qualified display name to 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)   
  
    # create a remote instance of a WinForms Form in a child AppDomain   
    "Creating remote WinForms Form in child AppDomain... "  
    $handle = $child.CreateInstance($assembly, "System.Windows.Forms.Form")   
  
    # examine returned ObjectHandle   
    "Returned object is a {0}" -f $handle.GetType()   
    $handle | gm # dump methods   
  
    # Did WinForms get pulled into our AppDomain?   
    "Is Windows Forms loaded in this AppDomain? {0}" -f (IsWinFormsLoaded)   
  
    # attempt to manipulate remote object, so unwrap   
    "Unwrapping, examining methods..."  
    $form = $handle.Unwrap()   
    $form | gm | select -first 10   
  
    # is Windows Forms loaded now?   
    "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.

参考

http://www.nivot.org/post/2007/12/07/WhyAppDomainsAreNotAMagicBullet

https://msdn.microsoft.com/en-us/library/ms173140(v=vs.80).aspx

https://msdn.microsoft.com/en-us/library/ms173139(v=vs.80).aspx