How to get Assembly when loading assembly using mono_assembly_load_from?

70 Views Asked by At

I load assemblies into the application using Mono methods. The problem is that when I load the assembly I get only IntPtr, but I need System.Reflection.Assembly. How to get it using IntPtr?

Methods I import and use:

public static class MonoCalls {
    [DllImport("__Internal", EntryPoint = "mono_image_open_from_data")]
    public static extern IntPtr MonoImageOpenFromData(IntPtr dataHandle, int dataLenght, bool shouldCopy, IntPtr status);

    [DllImport("__Internal", EntryPoint = "mono_assembly_load_from")]
    public static extern IntPtr MonoAssemblyLoadFrom(IntPtr imageHandle, string name, IntPtr status);
}

Class for loading an assembly into memory (the input is an assembly as an array of bytes):

public class Mono {
    IntPtr Image;
    IntPtr Assembly;
    public IntPtr Activate(byte[] Bytes) {
        unsafe {
            fixed (byte* Pointer = Bytes) {
                Image = MonoCalls.MonoImageOpenFromData((IntPtr)Pointer, Bytes.Length, true, IntPtr.Zero);
                Assembly = MonoCalls.MonoAssemblyLoadFrom(Image, string.Empty, IntPtr.Zero);
                return Assembly;
            }
        }
    }
}

Main code:

...

Mono Mono = new();
byte[] Assembly_Bytes = ...; // Assembly
IntPtr Pointer = Mono.Activate(Assembly_Bytes);
string MyAssemblyName = "MyAssembly";

Assembly FoundAssembly;
foreach (Assembly Assembly in AppDomain.CurrentDomain.GetAssemblies()) {
    if (Assembly.GetName().Name.Equals(MyAssemblyName)) {
        FoundAssembly = Assembly; // Got it (or an assembly with similar name)
        return;
    }
}

Type[] Types = FoundAssembly.GetTypes(); // Main purpose of this part of code
...

Is there any method like GetAssemblyByPtr(IntPtr) that returns System.Reflection.Assembly?

*Simple Assembly.Load() not suitable in my case.

1

There are 1 best solutions below

0
Cat On

Before loading an assembly I bind to the assembly loading event, in the event I receive the assembly. After loading, the event is unbinded.

Main code:

...
AppDomain.CurrentDomain.AssemblyLoad += CurrentDomain_AssemblyLoad;
...
// Loading assemblies
// It's supposed to load only the assemblies I need at the moment.
...
AppDomain.CurrentDomain.AssemblyLoad -= CurrentDomain_AssemblyLoad;
...
private void CurrentDomain_AssemblyLoad(object Sender, AssemblyLoadEventArgs AssemblyLoadEventArgs) {
    Console.WriteLine("CurrentDomain_AssemblyLoad");
    Assembly MyAssembly = AssemblyLoadEventArgs.LoadedAssembly;
    // Got loaded assembly (or assemblies)
}