65.9K
CodeProject is changing. Read more.
Home

Using SHBrowseForFolder in .NET

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.21/5 (6 votes)

May 26, 2006

CPOL

2 min read

viewsIcon

48221

Using SHBrowseForFolder in .NET

Update

This article is now mostly out of date. The functionality it describes now exists in the .NET class libraries natively (System.Windows.Forms.FolderBrowserDialog). The solution is still valid for anyone using .NET 1.0, which is likely to be very few people nowadays.

Introduction

There are many projects on The Code Project that try and solve the fact that the .NET class library does not have a folder picker dialog by writing their own version.

Windows already has a perfectly good folder picker, but it's not always obvious how to get access to it. While C++ has the SHBrowseForFolder function, there is no easy equivalent in .NET.

This short article describes how to gain access to this functionality from C#.

Using the Windows Folder Picker

The first thing to do is to add a reference to the shell32.dll. Select Project->Add Reference... then select Browse. Add the file c:\windows\system32\shell32.dll (or wherever you have Windows installed).

Once you have added that reference, you can use the following code to access the folder picker.

Shell32.Shell picker = new Shell32.ShellClass();
Shell32.Folder folder = picker.BrowseForFolder
                ((int)this.Handle, "Resource Updater", 0, 0);

if (folder == null)
    return; //user hit cancel

Shell32.FolderItem fi = (folder as Shell32.Folder3).Self;
string thePath = fi.Path;

Notes on the Code

If you just want to use the code, then you can ignore this section. Just copy and paste the above into your code and you're set to go.

The BrowseForFolder method is completely documented in the MSDN.

The call used here creates a default picker rooted at the My Computer location. The two "0"s as the last parameters are options that can modify the picker's behaviour, and are fully detailed in the MSDN entry.

The tricky part of the code is actually getting the path value from the returned object. A Shell Folder object is returned as the result (or null if the user hits cancel). This folder "object" is actually a COM+ interface pointer to a COM+ object. For simplicity, you can think of this just as a normal object though.

For some reason known only to Microsoft, this object doesn't actually have any direct way of getting the path value. What we need to do instead is gain access to the folder's FolderItem object, which does store the path. The Folder object returned is actually a base interface (think of this as a base class) which does not support the method we need. We cast it to the interface we require and can then gain access to the folder item (folder as Shell32.Folder3).

Once we have the folder item, we just ask it for the path.

Conclusion

As it turns out, gaining access to a standard folder picker is quite easy, and certainly faster than writing a class that does the same thing.

Hope someone finds this useful.