private void SetPropertiesFromDialogResult(NativeFolderBrowserDialog dialog) { dialog.GetResults(out IShellItemArray resultsArray); DirectoryNames.Clear(); resultsArray.GetCount(out uint count); for (uint i = 0; i < count; i++) { resultsArray.GetItemAt(i, out IShellItem result); HResult hr = result.GetDisplayName(NativeMethods.SIGDN.SIGDN_DESKTOPABSOLUTEPARSING, out IntPtr ppszName); if (hr == HResult.Ok && ppszName != IntPtr.Zero) { DirectoryNames.Add(Marshal.PtrToStringAuto(ppszName)); } Marshal.FreeCoTaskMem(ppszName); } if (DirectoryNames.Count > 0) { DirectoryName = DirectoryNames[0]; } }
private void SetDialogProperties(NativeFolderBrowserDialog dialog) { var flags = NativeMethods.FOS.FOS_PICKFOLDERS | NativeMethods.FOS.FOS_FORCEFILESYSTEM | NativeMethods.FOS.FOS_PATHMUSTEXIST | NativeMethods.FOS.FOS_FILEMUSTEXIST | NativeMethods.FOS.FOS_NOVALIDATE; if (MultiSelect) { flags |= NativeMethods.FOS.FOS_ALLOWMULTISELECT; } dialog.SetOptions(flags); if (!string.IsNullOrWhiteSpace(InitialDirectory)) { if (!Directory.Exists(InitialDirectory)) { try { // C:\Folder\File.exe becomes C:\Folder InitialDirectory = Path.GetDirectoryName(InitialDirectory) ?? ""; if (!Directory.Exists(InitialDirectory)) { return; } } // Fix: we weren't checking for invalid path names catch { return; } } var guid = new Guid(Guids.IShellItem); HResult result = NativeMethods.SHCreateItemFromParsingName( InitialDirectory, IntPtr.Zero, ref guid, out object item); if (result != HResult.Ok) { throw Marshal.GetExceptionForHR((int)result) ?? new Exception("Argh!\r\n" + result); } dialog.SetFolder((IShellItem)item); } }
protected override bool RunDialog(IntPtr hwndOwner) { NativeFolderBrowserDialog?dialog = null; try { dialog = new NativeFolderBrowserDialog(); SetDialogProperties(dialog); HResult result = dialog.Show(hwndOwner); if (result != HResult.Ok) { // ReSharper disable once ConvertIfStatementToReturnStatement if (result == HResult.Canceled) { return(false); } else { // I think I want to just ignore exceptions and cancel if anything at all went wrong, but // just in case I change my mind, here's the line to use: // throw Marshal.GetExceptionForHR((int)result); return(false); } } SetPropertiesFromDialogResult(dialog); return(true); } finally { if (dialog != null) { Marshal.FinalReleaseComObject(dialog); } } }