I have an entry assembly that is ran entirely in-memory. The entry assembly creates a new domain and then tries to attach an assembly resolver. This results in a FileNotFoundException within the new AppDomain because the OnResolveAssembly method is located in the entry assembly (in-memory) and the CLR is probing the disk looking for it.
Entry Assembly:
using System;
using System.Reflection;
public class Program
{
public static void Main()
{
var newDomain = AppDomain.CreateDomain("new-domain");
try { newDomain.AssemblyResolve += OnResolveAssembly; }
catch (Exception e) { Console.WriteLine(e); }
}
public static Assembly OnResolveAssembly(object sender, ResolveEventArgs args)
{
// load required dll from resource stream
return null;
}
}
Publish And Serve Entry Assembly:
dotnet publish
python -m http.server -d .\bin\Debug\net48\publish\
Run Entry Assembly In-Memory Via Powershell:
[System.Reflection.Assembly]::Load((Invoke-WebRequest "http://127.0.0.1:8000/test.exe").Content).EntryPoint.Invoke($null, $null)
Error:
System.IO.FileNotFoundException: Could not load file or assembly 'test, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
File name: 'test, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'
at System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, RuntimeAssembly reqAssembly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Reflection.RuntimeAssembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean forIntrospection)
at System.Reflection.RuntimeAssembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection)
at System.Reflection.Assembly.Load(String assemblyString)
at System.Runtime.Serialization.FormatterServices.LoadAssemblyFromString(String assemblyName)
at System.Reflection.MemberInfoSerializationHolder..ctor(SerializationInfo info, StreamingContext context)
at System.AppDomain.add_AssemblyResolve(ResolveEventHandler value)
at Program.Main()
This would be the offending line:
at System.Reflection.Assembly.Load(String assemblyString)
The same error will occur if I try to create a shared proxy object as well since the same process is applied of loading the containing assembly into the new domain:
var proxy = (Proxy) Domain.CreateInstanceAndUnwrap(typeof(Proxy).Assembly.FullName, typeof(Proxy).FullName);
I have tried manually loading assemblies into the new domain and while it does show they've been loaded, I am unable to do anything with them due to not being able to have a shared proxy object between domains.
Surely there is a way to run a C# binary entirely in-memory while retaining the ability to use AppDomain's.