Sqlite-net: FileLoadException on non-dev PC for pre-release

Created on 27 Mar 2018  路  5Comments  路  Source: praeclarum/sqlite-net

After using the pre-release NuGet package as suggested in #667, things work fine on my development machine.

Unfortunately, on all other Windows 10 machines, I get a Fusion load error:

FileLoadException

Die Datei oder Assembly "SQLitePCLRaw.batteries_v2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=8226ea5df37bcae9" oder eine Abh盲ngigkeit davon wurde nicht gefunden. Die gefundene Manifestdefinition der Assembly stimmt nicht mit dem Assemblyverweis 眉berein. (Ausnahme von HRESULT: 0x80131040)

(German).

Manually translated to English, this reads:

FileLoadException

The file or assembly \"SQLitePCLRaw.batteries_v2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=8226ea5df37bcae9\" or a dependency was not found. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

This is the failed Fusion log entry:

*** Protokolleintrag f眉r Assembly-Binder  (27.03.2018 @ 13:26:42) ***

Fehler bei diesem Vorgang.
Ergebnis der Bindung: hr = 0x80131040. Keine Beschreibung vorhanden.

Der Assemblymanager wurde geladen aus:  C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll
Als EXE-Datei ausgef眉hrt.  C:\Users\ukeim\AppData\Local\Zeta Producer 14\Applications\producer-core.exe
--- Ein detailliertes Fehlerprotokoll folgt. 

=== Zustandsinformationen vor Bindung ===
LOG: DisplayName = SQLitePCLRaw.batteries_v2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=8226ea5df37bcae9
 (Fully-specified)
LOG: Appbase = file:///C:/Users/ukeim/AppData/Local/Zeta Producer 14/Applications/
LOG: Urspr眉nglicher PrivatePath = NULL
LOG: DynamicBase = NULL
LOG: CacheBase = NULL
LOG: AppName = producer-core.exe
Aufruf von Assembly : SQLite-net, Version=1.1.0.0, Culture=neutral, PublicKeyToken=null.
===
LOG: Diese Bindung startet im default-Load-Kontext.
LOG: Die Anwendungskonfigurationsdatei wird verwendet: C:\Users\ukeim\AppData\Local\Zeta Producer 14\Applications\producer-core.exe.Config
LOG: Die Hostkonfigurationsdatei wird verwendet: 
LOG: Die Computerkonfigurationsdatei von C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config wird verwendet.
LOG: Verweis nach der Richtlinie: SQLitePCLRaw.batteries_v2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=8226ea5df37bcae9
LOG: Die Suche im GAC war nicht erfolgreich.
LOG: Download von neuem URL file:///C:/Users/ukeim/AppData/Local/Zeta Producer 14/Applications/SQLitePCLRaw.batteries_v2.DLL.
LOG: Der Assembly-Download wurde durchgef眉hrt. Datei-Setup wird begonnen: C:\Users\ukeim\AppData\Local\Zeta Producer 14\Applications\SQLitePCLRaw.batteries_v2.dll.
LOG: Die von der Quelle ausgef眉hrte Setup-Phase beginnt.
LOG: Der Assemblyname ist: SQLitePCLRaw.batteries_v2, Version=1.1.10.53, Culture=neutral, PublicKeyToken=8226ea5df37bcae9.
WRN: Der Vergleich des Assemblynamens f眉hrte zum Konflikt: Nebenversion.
ERR: Der Assemblyverweis entsprach nicht der gefundenen Assemblydefinition.
ERR: Die von der Quelle ausgef眉hrte Setup-Phase schlug mit hr = 0x80131040 fehl.
ERR: Das Setup der Assembly konnte nicht abgeschlossen werden (hr = 0x80131040). Die Suche wurde beendet.

(German only, sorry).


What I've tried

  • I've ensured that the DLL and all other SQLitePCL DLLs are present on the system.
  • I've inspected with CheckAsm and Dependency Walker to see any broken references (none found).
  • I've tried to install every C++ Runtime starting from 2012 up to 2017, both 32 and 64 bit on the system.
  • I've install full Visual Studio 2017 Community edition on the system.

No improvement whatsoever.


My question:

Any chance that this is an issue with the pre-release package?

Is a workaround available?

Most helpful comment

Oh, I just realized what the problem is. Starting with version 1.1.10, SQLitePCLRaw is setting the assembly version. Previously it was always set to 1.0.0.0. So you probably need a binding redirect.

All 5 comments

The mist likely problem is something us going wrong while deploying to the other machines.

To help diagnose it, we probably need to see exactly how you are copying things over to the other machines, and exactly what is being copied over, and exactly where the files are copied to.

Thanks, @ericsink. I've got a fully automated setup build process for my application (this one, BTW). This works since years.

Only after upgrading to the pre-release the above behaviour appears.

I'm more than happy to blame myself for this, since I then can fix it by myself.

Since even installing Visual Studio does not solve the issue, my strongest assumption (missing MSVC runtimes) seems to be wrong and I'm _really_ clueless now.

Even xcopying my working dev folder to the other machine does not solve the behaviour on the other machine.

Oh, I just realized what the problem is. Starting with version 1.1.10, SQLitePCLRaw is setting the assembly version. Previously it was always set to 1.0.0.0. So you probably need a binding redirect.

Awesome, that did the trick!

<dependentAssembly>
    <assemblyIdentity name="SQLitePCLRaw.core" publicKeyToken="1488e028ca7ab535" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-1.1.10.53" newVersion="1.1.10.53" />
</dependentAssembly>
<dependentAssembly>
    <assemblyIdentity name="SQLitePCLRaw.batteries_v2" publicKeyToken="8226ea5df37bcae9" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-1.1.10.53" newVersion="1.1.10.53" />
</dependentAssembly>

This was actually present in my dev environment and missing on my target system.

Thank you very much, @ericsink!

In case anyone is interested, I'm usally avoiding binding redirects by using the below approach, based on this Stack Overflow answer:

static class Program
{
    private static readonly IDictionary<string, Assembly> _additional =
        new Dictionary<string, Assembly>();

    static void Main()
    {
        // --
        // http://stackoverflow.com/a/9180843/107625

        var dir = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
        foreach (var assemblyName in Directory.GetFiles(dir, @"*.dll"))
        {
            var assembly = Assembly.LoadFile(assemblyName);
            _additional.Add(assembly.GetName().Name, assembly);
        }

        AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += CurrentDomain_ResolveAssembly;
        AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_ResolveAssembly;

        // --

        // ... Normal program code follows...

    }

    private static Assembly CurrentDomain_ResolveAssembly(object sender, ResolveEventArgs e)
    {
        // Here, I'm doing my own, automatic binding redirect.
        // (e. g. Newtonsoft.Json 6.0.0.0 to 9.0.0.0).

        var name = e.Name.Substring(0, e.Name.IndexOf(','));

        _additional.TryGetValue(name, out var res);
        return res;
    }
}
Was this page helpful?
0 / 5 - 0 ratings