com - How do I instantiate CorRuntimeHost from mscoree.tlb in PowerShell? -
i want enumerate appdomains in current process powershell. process happens visual studio, hosting studioshell. need instantiate corruntimhost, part of mscoree.tlb, can adapt this c# code..
i tried proper name of corruntimehost , pass new-object -comobject
"objectname". based on this forum posting, searched registry , think correct name clrmetadata.corruntimehost. however, while new-object -comobject 'clrmetadata.corruntimehost' -strict
return object, exposes methods intrinsic com object.
based on this stackoverflow question tried [activator]::createinstance(). however, following 2 statements give me same problem new-object, namely can't call icorruntimehost::enumdomains() method.
$corruntimehost = [activator]::createinstance([type]::gettypefromprogid('clrmetadata.corruntimehost')); $enumerator = $null; $corruntimehost.enumdomains([ref]$enumerator); method invocation failed because [system.__comobject] doesn't contain method named 'enumdomains'. @ line:1 char:1 + $corruntimehost.enumdomains([ref]$enumerator) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + categoryinfo : invalidoperation: (:) [], runtimeexception + fullyqualifiederrorid : methodnotfound
to working in powershell 3.0 ended having use assemblybuilder. below working code:
the problem seems there no public constructor mscoree.corruntimehostclass in .net 4.0 there in 3.5.
i later tested on windows 7 vm powershell 2.0 , code work in powershell 2.0 , 3.0.
$tlbname = split-path -parent ([appdomain]::currentdomain.getassemblies() | { $_.location -match '\\mscorlib.dll$' }).location $tlbname = join-path $tlbname 'mscoree.tlb'; $csharpstring = @" //adapted here http://blog.semanticsworks.com/2008/04/enumerating-appdomains.html using system; using system.collections.generic; using system.reflection; using system.reflection.emit; using system.runtime.interopservices; public class listprocessappdomains { [dllimport( `"oleaut32.dll`", charset = charset.unicode, preservesig = false )] private static extern void loadtypelibex (string strtypelibname, regkind regkind, [marshalas( unmanagedtype.interface )] out object typelib); private enum regkind { default = 0, register = 1, none = 2 } private class conversioneventhandler : itypelibimporternotifysink { public void reportevent( importereventkind eventkind, int eventcode, string eventmsg ) { console.error.writeline("kind: {0} code: {1} message"); } public assembly resolveref( object typelib ) { string stacktrace = system.environment.stacktrace; console.writeline("resolveref ({0})", typelib); console.writeline(stacktrace); return null; } } public static assemblybuilder loadmscoreedll( ref object typelib ) { conversioneventhandler eventhandler = new conversioneventhandler(); string assemblyname = "poshcomwrapper.dll"; loadtypelibex( @"$($tlbname)", regkind.none, out typelib ); typelibconverter typelibconverter = new typelibconverter(); return typelibconverter.converttypelibtoassembly( typelib, assemblyname, 0, eventhandler, null, null, null, null ); } } "@ # can run scipt multiple times try { [listprocessappdomains] } catch { add-type -typedefinition $csharpstring } function get-appdomain { $typelib = $null; $assemblybuilder = [listprocessappdomains]::loadmscoreedll([ref] $typelib) $corruntimehostclass = $assemblybuilder.createinstance('poshcomwrapper.corruntimehostclass') $enumhandle = [intptr]::zero $corruntimehostclass.enumdomains([ref] $enumhandle); $appdomain = $null; { $corruntimehostclass.nextdomain($enumhandle, [ref] $appdomain); if ($appdomain -ne $null -and $appdomain.gettype() -eq [appdomain]) { $appdomain; } } while ($appdomain -ne $null) } get-appdomain
Comments
Post a Comment