DLL hell with SQLite

前端 未结 3 757
栀梦
栀梦 2021-02-18 14:15

Some of our users are getting an issue with the version of sqlite.interop.dll that is being loaded at runtime, and it\'s a real head scratcher.

Background: A WPF applica

3条回答
  •  情深已故
    2021-02-18 15:16

    Our app has the same problem. As you mentioned, the problem is that Dell Backup and Recovery installs a shell extension that uses old versions of several popular dlls. They play hell with any app that launches file dialogs and also uses those libraries, because shell extensions load their dlls into your AppDomain. The only solution we have so far is to tell the users to uninstall Dell Backup and Recovery.

    If you force your app to load the correct library as dymanoid mentioned, then your app will crash when it displays a file dialog (because the shell extension will crash). If you don't do that, then your app will crash when it tries to read from its database.

    Interestingly, Dell Backup and Recovery is a repeat offender; it also breaks QT5 in the same way. The recommended solution from the QT guys is to compile your QT library under a different name with the -qtnamespace [name] option. We might be able to rig something like that with system.data.sqlite, but then we'd have to compile our own version.

    Microsoft is aware of the problem, but has declined to fix it.

    I wish the Dell guys had implemented their shell extension like this.

    Portroit Pro, SONAR, and AutoDesk's solution to this problem is also to uninstall Dell Backup and Recovery.

    A typical stack trace of the problem looks this in our application:

    System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt. 
    at System.Data.SQLite.UnsafeNativeMethods.sqlite3_open_interop(Byte[] utf8Filename, Int32 flags, IntPtr& db) 
    at System.Data.SQLite.SQLite3.Open(String strFilename, SQLiteConnectionFlags connectionFlags, SQLiteOpenFlagsEnum openFlags, Int32 maxPoolSize, Boolean usePool) 
    at System.Data.SQLite.SQLiteConnection.Open() 
    at STCommonShellIntegration.DataShellManagement.CreateNewConnection(SQLiteConnection& newConnection) 
    at STCommonShellIntegration.DataShellManagement.InitConfiguration(Dictionary`2 targetSettings) 
    at DBROverlayIcon.DBRBackupOverlayIcon.initComponent()
    

    So in answer to Track's comment, if you want to detect this particular problem and give the users some special notice, you could do something like this:

    AppDomain.CurrentDomain.UnhandledException += UEHandler;
    //...
    static void UEHandler(object sender, UnhandledExceptionEventArgs e){
      var ex = e.ExceptionObject as Exception;
      if( ex.ToString().Contains( "DBROverlayIcon" ){
        //show some dialog here telling users to uninstall DBaR
      }
    }
    

提交回复
热议问题