Click here to Skip to main content
16,020,811 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
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

C#
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;
        }
    }


C#
public class CustomFolderBrowserDialog : System.Windows.Forms.CommonDialog
    {
        private static readonly int MAX_PATH = 260;

        // Fields
        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;

        // Events
        public new event EventHandler HelpRequest
        {
            add
            {
                base.HelpRequest += value;
            }
            remove
            {
                base.HelpRequest -= value;
            }
        }

        public bool IsInvalidFolder { get; set; }

        // ctor
        public CustomFolderBrowserDialog()
        {
            IsInvalidFolder = false;
            this.Reset();
        }

        // Factory Methods
        public static CustomFolderBrowserDialog PrinterBrowser()
        {
            CustomFolderBrowserDialog x = new CustomFolderBrowserDialog();
            x.BecomePrinterBrowser();
            return x;
        }

        public static CustomFolderBrowserDialog ComputerBrowser()
        {
            CustomFolderBrowserDialog x = new CustomFolderBrowserDialog();
            x.BecomeComputerBrowser();
            return x;
        }


        // Helpers
        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
        {
            // messages FROM the folder browser
            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;

            // messages TO the folder browser
            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)
                        {
                            // get handle to the Edit box inside the Folder Browser Dialog
                            _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))
                        {
                            // we're browsing for a printer or computer, enable the OK button unconditionally.
                            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;
            //_uiFlags = 0;
            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(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
            //public static extern IntPtr FindWindowEx(HandleRef hwndParent, HandleRef hwndChildAfter, string lpszClass, string lpszWindow);
            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
        {
            // Methods
            [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.
Posted
Updated 12-Apr-16 1:18am
v2
Comments
Philippe Mori 12-Apr-16 12:23pm    
I prefer to use file ipen dialog for that purpose... You might be able to find samples on the web on how to do it.

Browse for folder has a somewhat old look and don't show files so it is sometime hard to know if you are at the desired location.

1 solution

OK, I tried it:
C#
FolderBrowserDialog fbd = new FolderBrowserDialog();
fbd.SelectedPath = @"D:\Temp";
if (fbd.ShowDialog() == DialogResult.OK)
    {
    Console.WriteLine(fbd.SelectedPath);
    }

I ran it in the debugger with a BP after the code, pressed "new folder", then OK and the string was
D:\Temp\New folder

Set the next statement back to the start and ran again. This time, it suggested "New Folder (2)" and I pressed "5", then OK.
The string was
D:\Temp\5
and the directory was correctly named.
So what am I doing that you aren't, or you doing that I'm not?
Because I use this control a fair amount, and have never had a problem...
 
Share this answer
 
Comments
Varun_Kumar 12-Apr-16 7:20am    
Hi, Thanks for your replay,
Here i use custom control , please check the code

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900