4

我正在尝试编写一个 C# 托管类来包装 SHGetKnownFolderPath,到目前为止它可以在 Vista 上运行,但由于在 shell32.dll 中找不到正确的函数,因此在 XP 上崩溃,正如预期的那样。

我想设置它,这样如果使用 XP,我可以使用 System.Environment.GetFolderPath 回退到一个(公认的 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);
        }
    }
4

2 回答 2

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();
  }
}
于 2009-06-09T13:35:44.010 回答
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
}
于 2009-06-09T13:38:22.553 回答