How to handle failed DllImport?

I am trying to write a managed class in C # to port SHGetKnownFolderPath while it is running on Vista, but it crashes on XP because I did not find the proper function in shell32.dll, as expected.

I want it to be configured in such a way that I can refuse (admittedly, a hacker) solution using System.Environment.GetFolderPath if you are using XP. (Or, better yet, if he cannot find funciton in shell32.)

Is there a way to do this other conditional compilation?

My current code is as follows:

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
source share
2 answers

Wrap your call on SHGetKnownFolderPath in a try-catch block. Catch a System.EntryPointNotFoundException , and then try an 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(); } } 
+9
source

You can check the OS version using the Environment.OSVersion property. I believe that if you do

 int osVersion = Environment.OSVersion.Version.Major 

on XP, which will be 5, and on Vista - 6. So, from there it’s just up to a simple check.

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

Source: https://habr.com/ru/post/1285964/


All Articles