How do I load an assembly as a reflection in a new AppDomain only?
I have experience in C # but relatively unfamiliar with concepts AppDomain
and the like. Anyway, I'm trying to put the assembly in a reflection-only context so that I can grab all of its namespaces. Here is the code I have right now (warning: PowerShell):
function Get-Namespaces($assembly)
{
$assemblyClass = [Reflection.Assembly]
$winmdClass = [Runtime.InteropServices.WindowsRuntime.WindowsRuntimeMetadata]
$domain = [AppDomain]::CurrentDomain
# Since desktop .NET can't work with winmd files,
# we have to use the reflection-only APIs and preload
# all the dependencies manually.
$appDomainHandler =
{
Param($sender, $e);
$assemblyClass::ReflectionOnlyLoad($e.Name)
}
$winmdHandler =
{
Param($sender, $e)
[string[]] $empty = @()
$path = $winmdClass::ResolveNamespace($e.NamespaceName, $empty) | select -Index 0
$e.ResolvedAssemblies.Add($assemblyClass::ReflectionOnlyLoadFrom($path))
}
# Hook up the handlers
$domain.add_ReflectionOnlyAssemblyResolve($appDomainHandler)
$winmdClass::add_ReflectionOnlyNamespaceResolve($winmdHandler)
# Do the actual work
$assemblyObject = $assemblyClass::ReflectionOnlyLoadFrom($assembly)
$types = $assemblyObject.GetTypes()
$namespaces = $types | ? IsPublic | select Namespace -Unique
# Deregister the handlers
$domain.remove_ReflectionOnlyAssemblyResolve($appDomainHandler)
$winmdClass::remove_ReflectionOnlyNamespaceResolve($winmdHandler)
return $namespaces
}
For some reason, when I run a function on assemblies like System.Xaml
or WindowsBase
, I get the following errors:
Exception calling "ReflectionOnlyLoadFrom" with "1" argument (s): "API restriction: The assembly 'file: /// C: \ Program Files (x86) \ Reference Assemblies \ Microsoft \ Framework \ .NETFramework \ v4.6.1 \ System.Xaml.dll 'has already loaded from a different location. It cannot be loaded from a new location within the same appdomain. " At C: \ Users \ James \ Code \ csharp \ Shims.Xaml \ generate.ps1: 50 char: 5 + $ assemblyObject = $ assemblyClass :: ReflectionOnlyLoadFrom ($ assembl ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~ + CategoryInfo: NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId: FileLoadException
So I would like to know how can I load the assembly in the new AppDomain? I checked MSDN but all I can find are methods like CreateInstanceAndUnwrap
which I can't / don't want to do as this is only reflection.
TL; DR: How do I load assemblies in a reflection-only context in a new AppDomain? Both C # and PowerShell code examples are welcome.
EDIT: Here is a GitHub gist script I made so others can reproduce the bug / test changes.
source to share