简体   繁体   English

如何处理失败的DllImport?

[英]How do I handle a failed DllImport?

I'm attempting to write a C# managed class to wrap SHGetKnownFolderPath, so far it works on Vista, but crashes on XP due to not finding the proper function in shell32.dll, as expected. 我正在尝试编写一个C#托管类来包装SHGetKnownFolderPath,到目前为止它可以在Vista上运行,但由于没有按预期在shell32.dll中找到正确的函数而在XP上崩溃。

I want to have it set so I can fallback on a (admittedly hacky) solution using System.Environment.GetFolderPath if using XP. 我想让它设置好所以如果使用XP,我可以使用System.Environment.GetFolderPath回避(通常是hacky)解决方案。 (Or, even better, if it can't find the funciton in shell32.) (或者,更好的是,如果它在shell32中找不到功能。)

Is there any way to do this other then conditional compilation? 除了条件编译之外,还有什么方法可以做到这一点吗?

My current code looks like: 我目前的代码如下:

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

Wrap your call to SHGetKnownFolderPath in a try-catch block. 在try-catch块中包含对SHGetKnownFolderPath的调用。 Catch the System.EntryPointNotFoundException and then try your alternative solution: 捕获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();
  }
}

You can check the OS version using the Environment.OSVersion property. 您可以使用Environment.OSVersion属性检查操作系统版本。 I believe if you do 我相信如果你这样做

int osVersion = Environment.OSVersion.Version.Major

on XP that will be 5, and on Vista that will be 6. So from there just to a simple check. 在XP上将是5,在Vista上将是6.所以从那里只是一个简单的检查。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM