libz does not handle assembly names from AppDomain.CurrentDomain.AssemblyResolve not fully qualified


Hello there!

First of all, excellent project!

I am having the same issue as described here, I'm getting a XamlParseException.

I debugged and found that AsmZResolver.TryLoadAssembly sometimes gets a resourceName like "EntityFramework.SqlServerCompact" or "MahApps.Metro, Culture=neutral" and this cannot be found in the ResourceNames dictionary, therefore loading fails.

I've verified this by adding following switch statement to the TryLoadAssembly method. After this, there is no longer an exception and the program works.
private static Assembly TryLoadAssembly(string resourceName)
    switch (resourceName)
        case "MahApps.Metro, Culture=neutral":
            resourceName = "MahApps.Metro, Version=, Culture=neutral, PublicKeyToken=f4fb5a3c4d1e5b4f";
        case "EntityFramework.SqlServerCompact":
            resourceName = "EntityFramework.SqlServerCompact, Version=, Culture=neutral, PublicKeyToken=b77a5c561934e089";
=>The bug in libz is that AppDomain.CurrentDomain.AssemblyResolve may pass an assembly name which is not fully qualified and libz does not handle it.
Closed Sep 12, 2014 at 3:58 PM by Krashan
Use "scenario 4"


Krashan wrote Sep 12, 2014 at 3:55 PM

There is no bug just a design decision (source: documentation).
NOTE: injecting dll (skipping the container part, see below) injects very simple assembly resolver. It is actually that simple that it cannot resolve assemblies by partial names. If you use partial names (for example, you use NHiberante and configure it with .hbm files) please use .libz container (embedded or not, doesn't matter). Only container resolver support partial names.

tbsbuc wrote Sep 15, 2014 at 6:16 AM

Thanks for the response. Point taken.

May I share my experience with this library though? Because I did come from ILMerge which indeed didn't do what I needed, so I searched for alternatives and tried libz. The tool completes successfully with no warning but the final exe just crashes. I suppose many people will stop right there.

Seeing that othe people have had this issue, why was this design decision taken? Can I help in implementing this feature?

From a user perspective this just doesn't make sense. If this was just a matter of being something still open and unfinished, I'd understand. But if this is on purpose, I don't.

tbsbuc wrote Sep 15, 2014 at 6:46 AM

Short follow up. The .libz solution does not work in my scenario because the partial name happens to be "MahApps.Metro, Culture=neutral". The "culture" is there for some reason and the LibZResolver cannot handle it either. I have no control over what gets passed to AppDomain.CurrentDomain.AssemblyResolve. .NET supports the mentioned string and Libz doesn't. Reopen?

tbsbuc wrote Sep 15, 2014 at 7:16 AM

Here's a possible patch for LibZResolver:
    private static IEnumerable<string> MatchByShortName(string shortAssemblyName)
        // PATCH: convert partial assembly names into short names
        if (shortAssemblyName.Contains(","))
            shortAssemblyName = shortAssemblyName.Split(new[] { ',' })[0];