Since my post about DsBrowseForContainer problem in Vista, I have been asked several times to provide the code on solution. So here we go – below is the class that I use to browse for OU container, it is written to .NET 3.5, but can be easily adapted to earlier versions as well:
public sealed class OUPickerDialog
{
public OUPickerDialog()
{
Caption = "The container picker";
Title = "Select a container:";
}
#region Imports
// all strings in structure will be marshaled as LPWStr
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
private struct DSBrowseInfo
{
public int structSize;
public IntPtr dlgOwner;
public string dlgCaption;
public string treeViewTitle;
public IntPtr rootPath;
// in/out string must be declared as String in struct/class, // not as StringBuilder public string path;
public int pathSize;
public int flags;
public IntPtr callback;
public IntPtr lParam;
public int returnFormat;
public string userName;
public string password;
public string objectClass;
public int objectClassSize;
};
[DllImport("dsuiext.dll", CharSet = CharSet.Unicode)]
private static extern int DsBrowseForContainerW(ref DSBrowseInfo info);
private const int DSBI_ENTIREDIRECTORY = 0x00090000;
private const int MAX_PATH = 256;
#endregion
#region Properties
/// <summary>
/// Gets or sets text to display on dialog box caption
/// </summary>
public string Caption { get; set; }
/// <summary>
/// Gets or sets title displayed above directory tree
/// </summary>
public string Title { get; set; }
/// <summary>
/// Gets or sets path to start browsing from
/// </summary>
public string RootPath { get; set; }
/// <summary>
/// Gets path selected by user or empty string if nothing has been selected
/// </summary>
public string SelectedPath { get; private set; }
/// <summary>
/// Gets name selected by user or empty string if nothing has been selected
/// </summary>
public string SelectedName { get; private set; }
#endregion
#region Methods
/// <summary>
/// Displays a modal picker dialog and returns OU path as selected by user or empty string if nothing
/// has been selected
/// </summary>
/// <returns><c>true</c> if user selected a unit or <c>false</c> otherwise</returns>
public bool? ShowDialog()
{
// initialize all members
SelectedPath = String.Empty;
SelectedName = String.Empty;
DSBrowseInfo dsbi = new DSBrowseInfo();
dsbi.structSize = Marshal.SizeOf(dsbi);
dsbi.dlgCaption = Caption;
dsbi.treeViewTitle = Title;
if (RootPath != null)
dsbi.rootPath = Marshal.StringToHGlobalAuto(RootPath);
dsbi.path = new string(new char[MAX_PATH]);
dsbi.pathSize = MAX_PATH;
dsbi.flags = DSBI_ENTIREDIRECTORY;
int status = DsBrowseForContainerW(ref dsbi);
bool? ret = false;
if (status == 1)
{
ret = true;
SelectedPath = dsbi.path;
SelectedName = CalcOUName(SelectedPath);
RootPath = Marshal.PtrToStringAuto(dsbi.rootPath);
}
return ret;
}
private static string CalcOUName(string ou)
{
int idx = 0;
do { idx = ou.IndexOf(@",", idx + 1);
} while (idx > 0 && ou[idx - 1] == '\\');
ou = ou.Substring(0, idx);
return ou;
}
#endregion
}
I have also uploaded a testing application I’ve been using. The code can be downloaded from here.
Technorati Tags:
.NET,
Vista
posted @ Monday, October 06, 2008 3:22 PM