using System; using System.Runtime.InteropServices; namespace FontPreview; internal static class NativeFolderDialog { private const uint FOS_PICKFOLDERS = 32u; private const int SIGDN_FILESYSPATH = -2147123200; [DllImport("shell32.dll", CharSet = CharSet.Unicode)] private static extern int SHCreateItemFromParsingName([MarshalAs(UnmanagedType.LPWStr)] string pszPath, IntPtr pbc, ref Guid riid, out IntPtr ppv); private static void AddNavPlace(IFileOpenDialog dlg, string clsidPath) { try { IntPtr ppv = IntPtr.Zero; Guid riid = new Guid("43826d1e-e718-42ee-bc55-a1e261c37bfe"); if (SHCreateItemFromParsingName(clsidPath, IntPtr.Zero, ref riid, out ppv) == 0 && ppv != IntPtr.Zero) { IShellItem psi = (IShellItem)Marshal.GetObjectForIUnknown(ppv); try { dlg.AddPlace(psi, 1); return; } catch { return; } } } catch { } } internal static string PickFolder(IntPtr owner, string title, string initialPath) { IFileOpenDialog fileOpenDialog = (IFileOpenDialog)new FileOpenDialogRCW(); try { fileOpenDialog.SetTitle(title); fileOpenDialog.SetOptions(32u); AddNavPlace(fileOpenDialog, "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}"); AddNavPlace(fileOpenDialog, "::{208D2C60-3AEA-1069-A2D8-08002B30309D}"); if (!string.IsNullOrEmpty(initialPath)) { try { IntPtr ppv = IntPtr.Zero; Guid riid = new Guid("43826d1e-e718-42ee-bc55-a1e261c37bfe"); if (SHCreateItemFromParsingName(initialPath, IntPtr.Zero, ref riid, out ppv) == 0 && ppv != IntPtr.Zero) { IShellItem folder = (IShellItem)Marshal.GetObjectForIUnknown(ppv); fileOpenDialog.SetFolder(folder); } } catch { } } if (fileOpenDialog.Show(owner) != 0) { return null; } fileOpenDialog.GetResult(out var ppsi); if (ppsi == null) { return null; } ppsi.GetDisplayName(-2147123200, out var ppszName); if (ppszName == IntPtr.Zero) { return null; } string result = Marshal.PtrToStringUni(ppszName); Marshal.FreeCoTaskMem(ppszName); return result; } finally { try { Marshal.FinalReleaseComObject(fileOpenDialog); } catch { } } } }