CurrentDomain.AssemblyResolve not being able resolve 'some' assemblies

7.1k views Asked by At

After finding the answer my last question on assembly resolving ( AppDomain.CurrentDomain.AssemblyResolve asking for a <AppName>.resources assembly? ) now i'm able to embed references assemblies on my program except that this does not work some references somehow.

First of all i setup my assembly resolver at the very first entrance of my Program.cs

    // attach our embedded assembly loader.
    AppDomain.CurrentDomain.AssemblyResolve += AssemblyManager.Instance.Resolver;

Here's my actual resolver;

public Assembly Resolver(object sender, ResolveEventArgs args)
{
    AssemblyName askedAssembly = new AssemblyName(args.Name);

    lock (this)
    {
        Assembly assembly;

        string resourceName = string.Format("Assets.Assemblies.{0}.dll", askedAssembly.Name);
        using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
        {
            if (stream == null)
            {
                LogManager.Instance.Write(LogMessageTypes.Fatal, string.Format("Can not resolve asked assembly: {0}", askedAssembly.Name));
                MessageBox.Show(i18n.CanNotLoadRequiredAssembliesMessage, i18n.CanNotLoadRequiredAssembliesTitle, MessageBoxButtons.OK, MessageBoxIcon.Error);
                Environment.Exit(-1);
            }

            byte[] assemblyData = new byte[stream.Length];
            stream.Read(assemblyData, 0, assemblyData.Length);
            assembly = Assembly.Load(assemblyData);
        }

        LogManager.Instance.Write(LogMessageTypes.Trace, "Loaded embedded assembly: " + askedAssembly.Name);

        return assembly;
    }
}

Now my program references these libraries assemblies.

  • Esent.Collections.dll
  • Esent.Interop.dll
  • HtmlAgilityPack.dll
  • Ionic.Zip.Reduced.dll
  • System.Windows.Forms.Calendar.dll
  • AxInterop.ShockwaveFlashObjects
  • Interop.ShockwaveFlashObjects
  • irrKlang.NET4.dll
  • ikpMP3.dll
  • Nini.dll (SOLVED)

With my resolver above; i can embed Esent.Collections, Esent.Interop, HtmlAgilityPack, Ionic.Zip.Reduced,System.Windows.Forms.Calendar,AxInterop.ShockwaveFlashObjects,Interop.ShockwaveFlashObjects and resolve those on run-time.

The problem arrives with irrKlang.NET.4, Nini and ShockwaveFlash assemblies in which if i try to embed these assemblies and try to resolve them at runtime i'm having problems.

For irrKlang i can understand the problem as irrKlang.NET4 assembly references unmanaged ikpMP3.dll which i can't find on it's own.

For the Nini.dll, actually i can embed this assembly and using VS debug/release configurations runned it just works okay but when i startup the program on my own from the explorer, the program just refuses to startup (with no errors or any bit of info).

Any help appreciated.

Update Now, thanks Marc Gravell's answer i can load the Nini.dll.

For the irrKlang part, as irrKlang.NET4.dll is a managed assembly which requires ikpMp3.dll -- an unmanaged one --, if i try to resolve irrKlang.NET4.dll on run-time it can access its required dependency ikpMp3. Is there work-around for this?

1

There are 1 answers

1
Marc Gravell On BEST ANSWER

A common problem here is to use the types before you have chance to register the assembly-resolve event. In particular, note that the system must be able to JIT a method before it can start running a method - including Main().

So if your entry-point (Main()) does the event hooking and also talks to the types in question, it will attempt to resolve the types (for JIT) before or has chance to subscribe.

Do the minimum in main; move the "real" code to another method, that is only invoked once the event is definitely subscribed.

For example:

static void Main() {
    SubscribeAssemblyResolver();
    ExecuteApplication();
}

In extreme cases you may even need to use MethodImplAttribute to disable inlining of the methods above.