代码之家  ›  专栏  ›  技术社区  ›  MiffTheFox

如何处理失败的DllImport?

  •  4
  • MiffTheFox  · 技术社区  · 17 年前

    我正试图编写一个C#托管类来包装SHGetKnownFolderPath,到目前为止它在Vista上工作,但在XP上崩溃,因为没有像预期的那样在shell32.dll中找到正确的函数。

    我想设置它,以便在使用XP的情况下使用System.Environment.GetFolderPath(无可否认是有黑客行为的)解决方案。(或者,如果在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);
            }
        }
    
    2 回复  |  直到 17 年前
        1
  •  9
  •   anikiforov heavyd    11 年前

    将对SHGetKnownFolderPath的调用包装在try-catch块中。赶上 然后尝试您的替代解决方案:

    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();
      }
    }
    
        2
  •  3
  •   BFree    17 年前

    您可以使用 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
    }
    
    推荐文章