2009-06-09 5 views
4

Je tente d'écrire une classe gérée C# pour envelopper SHGetKnownFolderPath, jusqu'à présent cela fonctionne sur Vista, mais se bloque sur XP en raison de ne pas trouver la fonction correcte dans shell32.dll, comme prévu.Comment gérer un DllImport échoué?

Je veux l'avoir configuré pour que je puisse me replier sur une solution (certes hacky) en utilisant System.Environment.GetFolderPath si j'utilise XP. (Ou, mieux encore, s'il ne trouve pas la fonction dans shell32.)

Y at-il un moyen de faire cette compilation autre que conditionnelle?

Mon code actuel ressemble à:

public abstract class KnownFolders 
    { 
     [DllImport("shell32.dll")] 
     private static extern int SHGetKnownFolderPath([MarshalAs(UnmanagedType.LPStruct)] Guid rfid, uint dwFlags, IntPtr hToken, out IntPtr pszPath); 

     // Trim properties to get various Guids. 

     public static string GetKnownFolderPath(Guid guid) 
     { 
      IntPtr pPath; 
      int result = SHGetKnownFolderPath(guid, 0, IntPtr.Zero, out pPath); 
      if (result == 0) 
      { 
       string s = Marshal.PtrToStringUni(pPath); 
       Marshal.FreeCoTaskMem(pPath); 
       return s; 
      } 
      else 
       throw new System.ComponentModel.Win32Exception(result); 
     } 
    } 

Répondre

9

Enveloppez votre appel à SHGetKnownFolderPath dans un bloc try-catch. Catch the System.EntryPointNotFoundException puis tenter votre solution de rechange:

public static string GetKnownFolderPath(Guid guid) 
{ 
    try 
    { 
    IntPtr pPath; 
    int result = SHGetKnownFolderPath(guid, 0, IntPtr.Zero, out pPath); 
    if (result == 0) 
    { 
     string s = Marshal.PtrToStringUni(pPath); 
     Marshal.FreeCoTaskMem(pPath); 
     return s; 
    } 
    else 
     throw new System.ComponentModel.Win32Exception(result); 
    } 
    catch(EntryPointNotFoundException ex) 
    { 
    DoAlternativeSolution(); 
    } 
} 
+0

D'accord, cela fonctionne, mais avec un petit changement. J'ai dû attraper une EntryPointNotFoundException, pas une exception DllNotFoundException. Voyant que la fonction provient de shell32.dll, il est peu probable qu'elle soit manquante sur une plateforme Windows fonctionnelle. – MiffTheFox

+0

Oui, c'est exact, je vais mettre à jour ma réponse pour refléter l'exception réelle. – heavyd

3

Vous pouvez vérifier la version du système d'exploitation en utilisant la propriété Environment.OSVersion. Je crois que si vous faites

int osVersion = Environment.OSVersion.Version.Major 

sur XP qui sera 5, et sur Vista qui sera 6. Donc à partir de là juste pour une simple vérification.

if(osVersion == 5) 
{ 
    //do XP way 
} 
else if(osVersion == 6) 
{ 
    //P/Invoke it 
} 
Questions connexes