2010-06-22 4 views
0

J'ai une application .NET écrite en C#. Mon application utilise des bibliothèques tierces, qui utilisent des bibliothèques tierces, qui s'appuient à leur tour sur l'existence de sqlceme35.dll (Microsoft SSCE). Quelque part le long de la ligne la dépendance sur sqlceme35.dll n'est pas pris en compte, et nous avons eu un certain nombre de situations où mon logiciel a été installé sur un ordinateur sans cette bibliothèque, l'application semble bien fonctionner pour la plupart des fonctions, mais se bloque d'une manière spectaculaire avec des messages d'erreur cryptiques lorsque nous arrivons au point où nous essayons d'appeler sqlceme35.dll.Vérification de la bibliothèque native dans le code managé .NET

Même si nous savons maintenant à quoi ressemblent les effets quand la bibliothèque n'est pas présente, j'aimerais toujours être plus proactif en détectant quand la bibliothèque n'est pas disponible et en donnant à l'utilisateur un message d'erreur amical problème, voici la solution ".

La question immédiate est: Comment puis-je détecter, lors de l'exécution, la présence de la bibliothèque sqlceme35.dll?

La plus grande question est: Comment puis-je détecter, lors de l'exécution, la présence de n'importe quel fichier .dll arbitraire, qu'il s'agisse d'un code natif ou d'une bibliothèque de code gérée?

+0

aide [? Comment puis-je détecter les DLL requises par une application] (http://stackoverflow.com/questions/362560/how-do-i-detect-the-dlls-requis-par-une-application) – lsalamon

Répondre

0

Nous intégrons les DLLs non gérées dans un assembly, puis les copions dans l'emplacement dll en cours d'exécution (pour les applications Web, le dossier bin de copie miroir). Cela garantit que la version correcte est en cours d'exécution pour une version particulière de notre application. Malheureusement, cela peut ne pas être faisable (légal) en fonction des conditions de licence pour vos diverses applications. Dans ces cas, votre meilleure option est susceptible d'utiliser LoadLibrary pour vérifier que la bibliothèque est trouvée, mais méfiez-vous de charger la mauvaise version (voir aussi: DLL hell); cela peut ou peut ne pas être un problème que vous pouvez même résoudre (pour nous, la seule solution était d'intégrer les dll et de les extraire des assemblages si nécessaire).

Voici notre code en question pour les pilotes Sybase ASE ADO:

public static class SybaseResourceExtractor { 
    public static void ExtractSybaseDependencies() { 
     ExtractSybaseDependency("QueryLibrary.Unmanaged.sybdrvado20.dll", "sybdrvado20.dll"); 
     ExtractSybaseDependency("QueryLibrary.Unmanaged.msvcr80.dll", "msvcr80.dll"); 
     ExtractSybaseDependency("QueryLibrary.Unmanaged.sybcsi_certicom_fips26.dll", "sybcsi_certicom_fips26.dll"); 
     ExtractSybaseDependency("QueryLibrary.Unmanaged.sybcsi_core26.dll", "sybcsi_core26.dll"); 
     ExtractSybaseDependency("QueryLibrary.Unmanaged.sbgse2.dll", "sbgse2.dll"); 
    } 

    /// <summary> 
    /// Extracts a resource to a file. 
    /// </summary> 
    /// <param name="resourceName">Name of the resource.</param> 
    /// <param name="filename">The filename including absolute path.</param> 
    static void ExtractSybaseDependency(string resourceName, string filename) { 
     try { 
      var assembly = Assembly.GetAssembly(typeof(AseConnection)); 
      var executingAssembly = Assembly.GetExecutingAssembly(); 
      filename = Path.GetDirectoryName(assembly.Location) + "\\" + filename; 

      if (File.Exists(filename)) { 
       File.Delete(filename);  
      } 

      if (!File.Exists(filename)) { 
       using (Stream s = executingAssembly.GetManifestResourceStream(resourceName)) { 
        using (var fs = new FileStream(filename, FileMode.Create)) { 
         if (s == null) { 
          throw new Exception("Failed to get resource stream for " + resourceName); 
         } 

         var b = new byte[s.Length]; 
         s.Read(b, 0, b.Length); 
         fs.Write(b, 0, b.Length); 
        } 
       } 
      } 
     } catch { 
      //Doing nothing 
     } 
    } 
1

Vous pouvez en utilisant PInvoke utiliser la fonction LoadLibrary, qui doit rechercher les mêmes endroits que Windows ne serait.

Questions connexes