I choose target folder to export my files using FolderBrowserDialog control in .net
I browsed folder 123 from desktop, and pressed "Make new Folder", it creates New folder named "New folder (2)", Before press any other place i modified the folder name to "5". Then press OK.
At that time i got an error "The selected folder does not exist. Please specify the correct folder path"
Here the path read as C:\Users\Manu\Desktop\123\New folder (2) instead of C:\Users\Manu\Desktop\123\5.
Here the issue is that after rename action, i didn't re-select the folder, So the new name not reflect to the folder path.
I need new folder name with out click on any other places.
How i resolve this issue
Here is my code
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
var fbd = ShowDialog("Select Destination Folder");
if (fbd == null) return;
}
public static string LastSelectedPath { get; set; }
public static CustomFolderBrowserDialog ShowDialog(string description)
{
var fbd = new CustomFolderBrowserDialog();
fbd.Description = description;
fbd.ShowNewFolderButton = true;
fbd.ShowEditBox = true;
fbd.ShowFullPathInEditBox = true;
if (!string.IsNullOrEmpty(LastSelectedPath)) fbd.SelectedPath = LastSelectedPath;
if (fbd.ShowDialog() != System.Windows.Forms.DialogResult.OK) return null;
if (fbd.IsInvalidFolder)
{
MessageBox.Show("Invalid Folder Path");
return null;
}
LastSelectedPath = fbd.SelectedPath;
MessageBox.Show(fbd.SelectedPath);
return fbd;
}
}
public class CustomFolderBrowserDialog : System.Windows.Forms.CommonDialog
{
private static readonly int MAX_PATH = 260;
private PInvoke.BrowseFolderCallbackProc _callback;
private string _descriptionText;
private Environment.SpecialFolder _rootFolder;
private string _selectedPath;
private bool _selectedPathNeedsCheck;
private bool _showNewFolderButton;
private bool _showEditBox;
private bool _showBothFilesAndFolders;
private bool _newStyle = true;
private bool _showFullPathInEditBox = true;
private bool _dontIncludeNetworkFoldersBelowDomainLevel;
private int _uiFlags;
private IntPtr _hwndEdit;
private IntPtr _rootFolderLocation;
public new event EventHandler HelpRequest
{
add
{
base.HelpRequest += value;
}
remove
{
base.HelpRequest -= value;
}
}
public bool IsInvalidFolder { get; set; }
public CustomFolderBrowserDialog()
{
IsInvalidFolder = false;
this.Reset();
}
public static CustomFolderBrowserDialog PrinterBrowser()
{
CustomFolderBrowserDialog x = new CustomFolderBrowserDialog();
x.BecomePrinterBrowser();
return x;
}
public static CustomFolderBrowserDialog ComputerBrowser()
{
CustomFolderBrowserDialog x = new CustomFolderBrowserDialog();
x.BecomeComputerBrowser();
return x;
}
private void BecomePrinterBrowser()
{
_uiFlags += BrowseFlags.BIF_BROWSEFORPRINTER;
Description = "Select a printer:";
PInvoke.Shell32.SHGetSpecialFolderLocation(IntPtr.Zero, CSIDL.PRINTERS, ref this._rootFolderLocation);
ShowNewFolderButton = false;
ShowEditBox = false;
}
private void BecomeComputerBrowser()
{
_uiFlags += BrowseFlags.BIF_BROWSEFORCOMPUTER;
Description = "Select a computer:";
PInvoke.Shell32.SHGetSpecialFolderLocation(IntPtr.Zero, CSIDL.NETWORK, ref this._rootFolderLocation);
ShowNewFolderButton = false;
ShowEditBox = false;
}
private class CSIDL
{
public const int PRINTERS = 4;
public const int NETWORK = 0x12;
}
private class BrowseFlags
{
public const int BIF_DEFAULT = 0x0000;
public const int BIF_BROWSEFORCOMPUTER = 0x1000;
public const int BIF_BROWSEFORPRINTER = 0x2000;
public const int BIF_BROWSEINCLUDEFILES = 0x4000;
public const int BIF_BROWSEINCLUDEURLS = 0x0080;
public const int BIF_DONTGOBELOWDOMAIN = 0x0002;
public const int BIF_EDITBOX = 0x0010;
public const int BIF_NEWDIALOGSTYLE = 0x0040;
public const int BIF_NONEWFOLDERBUTTON = 0x0200;
public const int BIF_RETURNFSANCESTORS = 0x0008;
public const int BIF_RETURNONLYFSDIRS = 0x0001;
public const int BIF_SHAREABLE = 0x8000;
public const int BIF_STATUSTEXT = 0x0004;
public const int BIF_UAHINT = 0x0100;
public const int BIF_VALIDATE = 0x0020;
public const int BIF_NOTRANSLATETARGETS = 0x0400;
}
private static class BrowseForFolderMessages
{
public const int BFFM_INITIALIZED = 1;
public const int BFFM_SELCHANGED = 2;
public const int BFFM_VALIDATEFAILEDA = 3;
public const int BFFM_VALIDATEFAILEDW = 4;
public const int BFFM_IUNKNOWN = 5;
public const int BFFM_SETSTATUSTEXT = 0x464;
public const int BFFM_ENABLEOK = 0x465;
public const int BFFM_SETSELECTIONA = 0x466;
public const int BFFM_SETSELECTIONW = 0x467;
}
private int FolderBrowserCallback(IntPtr hwnd, int msg, IntPtr lParam, IntPtr lpData)
{
switch (msg)
{
case BrowseForFolderMessages.BFFM_INITIALIZED:
if (this._selectedPath.Length != 0)
{
PInvoke.User32.SendMessage(new HandleRef(null, hwnd), BrowseForFolderMessages.BFFM_SETSELECTIONW, 1, this._selectedPath);
if (this._showEditBox && this._showFullPathInEditBox)
{
_hwndEdit = PInvoke.User32.FindWindowEx(new HandleRef(null, hwnd), IntPtr.Zero, "Edit", null);
PInvoke.User32.SetWindowText(_hwndEdit, this._selectedPath);
}
}
break;
case BrowseForFolderMessages.BFFM_SELCHANGED:
IntPtr pidl = lParam;
if (pidl != IntPtr.Zero)
{
if (((_uiFlags & BrowseFlags.BIF_BROWSEFORPRINTER) == BrowseFlags.BIF_BROWSEFORPRINTER) ||
((_uiFlags & BrowseFlags.BIF_BROWSEFORCOMPUTER) == BrowseFlags.BIF_BROWSEFORCOMPUTER))
{
PInvoke.User32.SendMessage(new HandleRef(null, hwnd), BrowseForFolderMessages.BFFM_ENABLEOK, 0, 1);
}
else
{
IntPtr pszPath = Marshal.AllocHGlobal(MAX_PATH * Marshal.SystemDefaultCharSize);
bool haveValidPath = PInvoke.Shell32.SHGetPathFromIDList(pidl, pszPath);
String displayedPath = Marshal.PtrToStringAuto(pszPath);
Marshal.FreeHGlobal(pszPath);
PInvoke.User32.SendMessage(new HandleRef(null, hwnd), BrowseForFolderMessages.BFFM_ENABLEOK, 0, haveValidPath ? 1 : 0);
if (haveValidPath && !String.IsNullOrEmpty(displayedPath))
{
if (_showEditBox && _showFullPathInEditBox)
{
IntPtr hwndEdit = _hwndEdit;
if (hwndEdit == IntPtr.Zero) hwndEdit = PInvoke.User32.FindWindowEx(new HandleRef(null, hwnd), IntPtr.Zero, "Edit",
null);
if (hwndEdit != IntPtr.Zero)
PInvoke.User32.SetWindowText(hwndEdit, displayedPath);
}
if ((_uiFlags & BrowseFlags.BIF_STATUSTEXT) == BrowseFlags.BIF_STATUSTEXT)
PInvoke.User32.SendMessage(new HandleRef(null, hwnd), BrowseForFolderMessages.BFFM_SETSTATUSTEXT, 0, displayedPath);
}
}
}
break;
case BrowseForFolderMessages.BFFM_IUNKNOWN:
if (lParam == IntPtr.Zero)
{
IntPtr hwndEdit = PInvoke.User32.FindWindowEx(new HandleRef(null, hwnd), IntPtr.Zero, "Edit",
null);
int lng = PInvoke.User32.GetWindowTextLength(hwndEdit);
StringBuilder sb = new StringBuilder(lng + 1);
PInvoke.User32.GetWindowText(hwndEdit, sb, sb.Capacity);
string folder = sb.ToString();
if (!System.IO.Directory.Exists(folder)) IsInvalidFolder = true;
}
break;
}
return 0;
}
private static PInvoke.IMalloc GetSHMalloc()
{
PInvoke.IMalloc[] ppMalloc = new PInvoke.IMalloc[1];
PInvoke.Shell32.SHGetMalloc(ppMalloc);
return ppMalloc[0];
}
public override void Reset()
{
this._rootFolder = (Environment.SpecialFolder)0;
this._descriptionText = string.Empty;
this._selectedPath = string.Empty;
this._selectedPathNeedsCheck = false;
this._showNewFolderButton = true;
this._showEditBox = true;
this._newStyle = true;
this._dontIncludeNetworkFoldersBelowDomainLevel = false;
this._hwndEdit = IntPtr.Zero;
this._rootFolderLocation = IntPtr.Zero;
}
protected override bool RunDialog(IntPtr hWndOwner)
{
bool result = false;
if (_rootFolderLocation == IntPtr.Zero)
{
PInvoke.Shell32.SHGetSpecialFolderLocation(hWndOwner, (int)this._rootFolder, ref _rootFolderLocation);
if (_rootFolderLocation == IntPtr.Zero)
{
PInvoke.Shell32.SHGetSpecialFolderLocation(hWndOwner, 0, ref _rootFolderLocation);
if (_rootFolderLocation == IntPtr.Zero)
{
throw new InvalidOperationException("FolderBrowserDialogNoRootFolder");
}
}
}
_hwndEdit = IntPtr.Zero;
if (_dontIncludeNetworkFoldersBelowDomainLevel)
_uiFlags += BrowseFlags.BIF_DONTGOBELOWDOMAIN;
if (this._newStyle)
_uiFlags += BrowseFlags.BIF_NEWDIALOGSTYLE;
if (!this._showNewFolderButton)
_uiFlags += BrowseFlags.BIF_NONEWFOLDERBUTTON;
if (this._showEditBox)
_uiFlags += BrowseFlags.BIF_EDITBOX;
if (this._showBothFilesAndFolders)
_uiFlags += BrowseFlags.BIF_BROWSEINCLUDEFILES;
if (Control.CheckForIllegalCrossThreadCalls && (Application.OleRequired() != ApartmentState.STA))
{
throw new ThreadStateException("DebuggingException: ThreadMustBeSTA");
}
IntPtr pidl = IntPtr.Zero;
IntPtr hglobal = IntPtr.Zero;
IntPtr pszPath = IntPtr.Zero;
try
{
PInvoke.BROWSEINFO browseInfo = new PInvoke.BROWSEINFO();
hglobal = Marshal.AllocHGlobal(MAX_PATH * Marshal.SystemDefaultCharSize);
pszPath = Marshal.AllocHGlobal(MAX_PATH * Marshal.SystemDefaultCharSize);
this._callback = new PInvoke.BrowseFolderCallbackProc(this.FolderBrowserCallback);
browseInfo.pidlRoot = _rootFolderLocation;
browseInfo.Owner = hWndOwner;
browseInfo.pszDisplayName = hglobal;
browseInfo.Title = this._descriptionText;
browseInfo.Flags = _uiFlags;
browseInfo.callback = this._callback;
browseInfo.lParam = IntPtr.Zero;
browseInfo.iImage = 0;
pidl = PInvoke.Shell32.SHBrowseForFolder(browseInfo);
if (((_uiFlags & BrowseFlags.BIF_BROWSEFORPRINTER) == BrowseFlags.BIF_BROWSEFORPRINTER) ||
((_uiFlags & BrowseFlags.BIF_BROWSEFORCOMPUTER) == BrowseFlags.BIF_BROWSEFORCOMPUTER))
{
this._selectedPath = Marshal.PtrToStringAuto(browseInfo.pszDisplayName);
result = true;
}
else
{
if (pidl != IntPtr.Zero)
{
PInvoke.Shell32.SHGetPathFromIDList(pidl, pszPath);
this._selectedPathNeedsCheck = true;
this._selectedPath = Marshal.PtrToStringAuto(pszPath);
result = true;
}
}
}
finally
{
PInvoke.IMalloc sHMalloc = GetSHMalloc();
sHMalloc.Free(_rootFolderLocation);
_rootFolderLocation = IntPtr.Zero;
if (pidl != IntPtr.Zero)
{
sHMalloc.Free(pidl);
}
if (pszPath != IntPtr.Zero)
{
Marshal.FreeHGlobal(pszPath);
}
if (hglobal != IntPtr.Zero)
{
Marshal.FreeHGlobal(hglobal);
}
this._callback = null;
}
return result;
}
public string Description
{
get
{
return this._descriptionText;
}
set
{
this._descriptionText = (value == null) ? string.Empty : value;
}
}
public Environment.SpecialFolder RootFolder
{
get
{
return this._rootFolder;
}
set
{
if (!Enum.IsDefined(typeof(Environment.SpecialFolder), value))
{
throw new InvalidEnumArgumentException("value", (int)value, typeof(Environment.SpecialFolder));
}
this._rootFolder = value;
}
}
private object _lockSelectedPath = new object();
public string SelectedPath
{
get
{
lock (_lockSelectedPath)
{
if (((this._selectedPath != null) && (this._selectedPath.Length != 0)) &&
this._selectedPathNeedsCheck)
{
new FileIOPermission(FileIOPermissionAccess.PathDiscovery, this._selectedPath).Demand();
this._selectedPathNeedsCheck = false;
}
return this._selectedPath;
}
}
set
{
lock (_lockSelectedPath)
{
this._selectedPath = (value == null) ? string.Empty : value;
this._selectedPathNeedsCheck = true;
}
}
}
public bool ShowNewFolderButton
{
get
{
return this._showNewFolderButton;
}
set
{
this._showNewFolderButton = value;
}
}
public bool ShowEditBox
{
get
{
return this._showEditBox;
}
set
{
this._showEditBox = value;
}
}
public bool NewStyle
{
get
{
return this._newStyle;
}
set
{
this._newStyle = value;
}
}
public bool DontIncludeNetworkFoldersBelowDomainLevel
{
get { return _dontIncludeNetworkFoldersBelowDomainLevel; }
set { _dontIncludeNetworkFoldersBelowDomainLevel = value; }
}
public bool ShowFullPathInEditBox
{
get { return _showFullPathInEditBox; }
set { _showFullPathInEditBox = value; }
}
public bool ShowBothFilesAndFolders
{
get { return _showBothFilesAndFolders; }
set { _showBothFilesAndFolders = value; }
}
}
internal static class PInvoke
{
static PInvoke() { }
public delegate int BrowseFolderCallbackProc(IntPtr hwnd, int msg, IntPtr lParam, IntPtr lpData);
internal static class User32
{
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SendMessage(HandleRef hWnd, int msg, int wParam, string lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SendMessage(HandleRef hWnd, int msg, int wParam, int lParam);
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindowEx(HandleRef hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
[DllImport("user32.dll", SetLastError = true)]
public static extern Boolean SetWindowText(IntPtr hWnd, String text);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern int GetWindowTextLength(IntPtr hWnd);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
}
[ComImport, Guid("00000002-0000-0000-c000-000000000046"), SuppressUnmanagedCodeSecurity, InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IMalloc
{
[PreserveSig]
IntPtr Alloc(int cb);
[PreserveSig]
IntPtr Realloc(IntPtr pv, int cb);
[PreserveSig]
void Free(IntPtr pv);
[PreserveSig]
int GetSize(IntPtr pv);
[PreserveSig]
int DidAlloc(IntPtr pv);
[PreserveSig]
void HeapMinimize();
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public class BROWSEINFO
{
public IntPtr Owner;
public IntPtr pidlRoot;
public IntPtr pszDisplayName;
public string Title;
public int Flags;
public BrowseFolderCallbackProc callback;
public IntPtr lParam;
public int iImage;
}
internal static class Shell32
{
[DllImport("shell32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SHBrowseForFolder([In] PInvoke.BROWSEINFO lpbi);
[DllImport("shell32.dll")]
public static extern int SHGetMalloc([Out, MarshalAs(UnmanagedType.LPArray)] PInvoke.IMalloc[] ppMalloc);
[DllImport("shell32.dll", CharSet = CharSet.Auto)]
public static extern bool SHGetPathFromIDList(IntPtr pidl, IntPtr pszPath);
[DllImport("shell32.dll")]
public static extern int SHGetSpecialFolderLocation(IntPtr hwnd, int csidl, ref IntPtr ppidl);
}
}
Thanks in advance.
What I have tried:
I tried to read from Selected path, it always get the incorrect path.