2009-06-09 66 views
4

我試圖編寫一個C#託管類來包裝SHGetKnownFolderPath,到目前爲止它在Vista上工作,但由於在shell32.dll中找不到正確的函數而導致XP崩潰,如預期的那樣。如何處理失敗的DllImport?

我想讓它設置好,這樣我就可以在使用System.Environment.GetFolderPath(如果使用XP)的情況下回退(肯定是hacky)解決方案。 (或者,甚至更好,如果它在shell32中找不到功能。)

有沒有其他方法可以做到這一點,然後條件編譯?

我當前的代碼看起來像:

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); 
     } 
    } 

回答

9

包裝你到SHGetKnownFolderPath調用在try-catch塊。抓住System.EntryPointNotFoundException,然後嘗試你的替代解決方案:

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

好的,這個工作,但有一個小的變化。我不得不捕獲一個EntryPointNotFoundException,而不是一個DllNotFoundException。從功能上來看,shell32.dll是不可能在功能性Windows平臺上缺失的。 – MiffTheFox 2009-06-09 14:00:51

3

您可以使用Environment.OSVersion酒店辦理入住手續的操作系統版本。我相信,如果你這樣做

int osVersion = Environment.OSVersion.Version.Major 
在XP

,這將是5,而在Vista上,這將是6,所以從那裏只是一個簡單的檢查。

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