/EnumAppDomains.ps1 Secret
Last active
December 17, 2015 07:28
My attempts to get mscoree.tlb loaded at runtime with powershell. The working code is EnumAppDomains.ps1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# adapted from here http://blog.semanticsworks.com/2008/04/enumerating-appdomains.html | |
$csharpString = @" | |
using System; | |
using System.Collections.Generic; | |
using System.Runtime.InteropServices; | |
public class ListProcessAppDomains | |
{ | |
private static extern void LoadTypeLibEx | |
(String strTypeLibName, RegKind regKind, | |
[MarshalAs( UnmanagedType.Interface )] out Object typeLib); | |
private enum RegKind | |
{ | |
RegKind_Default = 0, | |
RegKind_Register = 1, | |
RegKind_None = 2 | |
} | |
private class ConversionEventHandler : ITypeLibImporterNotifySink | |
{ | |
private void ReportEvent( ImporterEventKind eventKind, int eventCode, string eventMsg ) | |
{ | |
Console.Error.WriteLine("Kind: {0} Code: {1} Message"); | |
} | |
public Assembly ResolveRef( object typeLib ) | |
{ | |
// resolve reference here and return a correct assembly... | |
//This is where im not sure how to do it | |
return null; | |
} | |
} | |
static ListProcessAppDomains() { | |
} | |
public static IList<AppDomain> GetAppDomains() | |
{ | |
var appDomains = new List<AppDomain>(); | |
IntPtr enumHandle = IntPtr.Zero; | |
dynamic host = Activator.CreateInstance(Type.GetTypeFromProgID("CLRMetaData.CorRuntimeHost")); | |
try | |
{ | |
host.EnumDomains(out enumHandle); | |
object domain = null; | |
while (true) | |
{ | |
host.NextDomain(enumHandle, out domain); | |
if (domain == null) break; | |
AppDomain appDomain = (AppDomain)domain; | |
appDomains.Add(appDomain); | |
} | |
return appDomains; | |
} | |
catch (Exception e) | |
{ | |
Console.Error.WriteLine(e.ToString()); | |
return null; | |
} | |
finally | |
{ | |
host.CloseEnum(enumHandle); | |
Marshal.ReleaseComObject(host); | |
} | |
} | |
} | |
"@ | |
Add-Type -TypeDefinition $csharpString |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$tlbName = Split-Path -Parent ([AppDomain]::CurrentDomain.GetAssemblies() | Where { $_.Location -Match '\\mscorlib.dll$' }).Location | |
$tlbName = Join-Path $tlbName 'mscoree.tlb'; | |
$csharpString = @" | |
//adapted from 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 ); | |
} | |
} | |
"@ | |
# So we can run this 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; | |
do | |
{ | |
$corRuntimeHostClass.NextDomain($enumHandle, [ref] $appDomain); | |
if ($appDomain -ne $null -and $appDomain.GetType() -eq [AppDomain]) { $appDomain; } | |
} while ($appDomain -ne $null) | |
} | |
Get-AppDomain |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$tlbName = Split-Path -Parent ([AppDomain]::CurrentDomain.GetAssemblies() | Where Location -Match '\\mscorlib.dll$').Location | |
$tlbName = Join-Path $tlbName 'mscoree.tlb'; | |
$csharpString = @" | |
//adapted from 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 ) | |
{ | |
var stackTrace = System.Environment.StackTrace; | |
Console.WriteLine("ResolveRef ({0})", typeLib); | |
Console.WriteLine(stackTrace); | |
return null; | |
} | |
} | |
public static AssemblyBuilder LoadMsCoreeDll( ref Object typeLib ) { | |
var eventHandler = new ConversionEventHandler(); | |
var assemblyName = "PoshComWrapper.dll"; | |
LoadTypeLibEx( @"$($tlbName)", RegKind.None, out typeLib ); | |
var typeLibConverter = new TypeLibConverter(); | |
return typeLibConverter.ConvertTypeLibToAssembly( typeLib, assemblyName, 0, eventHandler, null, null, null, null ); | |
} | |
} | |
"@ | |
# So we can run this 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; | |
do | |
{ | |
$corRuntimeHostClass.NextDomain($enumHandle, [ref] $appDomain); | |
if ($appDomain -ne $null -and $appDomain.GetType() -eq [AppDomain]) { $appDomain; } | |
} while ($appDomain -ne $null) | |
} | |
Get-AppDomain |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add-Type -Namespace "JustAProgramer" -Name 'LoadTypeHelper' -MemberDefinition "[ DllImport( `"oleaut32.dll`", CharSet = CharSet.Unicode, PreserveSig = false )] | |
public static extern void LoadTypeLibEx( String strTypeLibName, RegKind regKind, | |
[ MarshalAs( UnmanagedType.Interface )] out Object typeLib ); | |
public enum RegKind | |
{ | |
RegKind_Default = 0, | |
RegKind_Register = 1, | |
RegKind_None = 2 | |
}" | |
$tlbName = 'C:\Windows\Microsoft.NET\Framework64\v4.0.30319\mscoree.tlb'; | |
$dllName = [IO.Path]::GetTempFileName() | |
$typeLibConverter = New-Object Runtime.InteropServices.TypeLibConverter | |
$typeLib = $null; | |
[JustAProgramer.LoadTypeHelper]::LoadTypeLibEx( $tlbName, [JustAProgramer.LoadTypeHelper+RegKind]::RegKind_None, [ref] $typeLib ); | |
#$typeLibConverter | gm | |
#$typeLibConverter.ConvertTypeLibToAssembly | |
$typeLib | |
[AssemblyBuilder] $asm = $typeLibConverter.ConvertTypeLibToAssembly($typeLib, $dllName, 0, $null, $null, $null, $null, $null ); | |
$asm.Save( "ExplorerLib.dll" ); | |
if (Test-Path $dllName) { | |
rm -Force $dllName | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Runtime.InteropServices; | |
using mscoree; | |
// This code does not work in .NET 4.0. It does compile in .NET 3.5 | |
namespace ConsoleApplication2 | |
{ | |
internal static class Program | |
{ | |
static void Main() | |
{ | |
foreach (var appDomain in GetAppDomains()) | |
{ | |
Console.WriteLine("Name: {0} Id: {1} Config file: {2}", appDomain.FriendlyName, appDomain.Id, appDomain.SetupInformation.ConfigurationFile); | |
} | |
Console.Write("Press any key to continue . . . "); | |
Console.ReadKey(true); | |
} | |
private static IList<AppDomain> GetAppDomains() | |
{ | |
var appDomains = new List<AppDomain>(); | |
IntPtr enumHandle = IntPtr.Zero; | |
var host = new CorRuntimeHostClass(); | |
try | |
{ | |
host.EnumDomains(out enumHandle); | |
object domain; | |
do | |
{ | |
host.NextDomain(enumHandle, out domain); | |
if (domain == null) break; | |
var appDomain = (AppDomain) domain; | |
appDomains.Add(appDomain); | |
} while (domain != null); | |
} | |
catch (Exception e) | |
{ | |
Console.WriteLine(e.ToString()); | |
return null; | |
} | |
finally | |
{ | |
host.CloseEnum(enumHandle); | |
Marshal.ReleaseComObject(host); | |
} | |
return appDomains; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment