问题
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.
I want to have it set so I can fallback on a (admittedly hacky) solution using System.Environment.GetFolderPath if using XP. (Or, even better, if it can't find the funciton in 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);
}
}
回答1:
Wrap your call to SHGetKnownFolderPath in a try-catch block. Catch the System.EntryPointNotFoundException and then try your alternative solution:
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:
You can check the OS version using the Environment.OSVersion property. 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.
if(osVersion == 5)
{
//do XP way
}
else if(osVersion == 6)
{
//P/Invoke it
}
来源:https://stackoverflow.com/questions/970017/how-do-i-handle-a-failed-dllimport