ActiveDir Sample

This sample demonstrates how to adjust the default apartment setting of a managed object passing data to an unmanaged method that calls the CoInitialize method. The CoInitialize method initializes a COM library in a single-threaded apartment (STA). By default, C# clients are initialized in multithreaded apartments (MTA). Visual Basic 2005 clients are initialized as STA objects and do not need to be adjusted.

The ActiveDir sample uses the following unmanaged method, shown with its original function declaration:

  • DsBrowseForContainer exported from Dsuiext.dll.

    int DsBrowseForContainer(PDSBROWSEINFO pInfo);

In C#, the STAThreadAttribute attribute creates an STA apartment. Because STA is the default apartment setting for Visual Basic 2005 clients, no attribute is required. The Marshal.SizeOf method dynamically calculates the size of the unmanaged structure.

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
public struct DsBrowseInfo
    public const int MAX_PATH = 256;

    public int       Size;
    public IntPtr    OwnerHandle;
    public string    Caption;
    public string    Title;
    public string    Root;
    public string    Path;
    public int       PathSize;
    public int       Flags;
    public IntPtr    Callback;
    public int       Param;
    public int       ReturnFormat;
    public string    UserName;
    public string    Password;
    public string    ObjectClass;
    public int       ObjectClassSize;

public class LibWrap
    // Declares a managed prototype for the unmanaged function.
    [DllImport("dsuiext.dll", CharSet=CharSet.Unicode)]
    public static extern int DsBrowseForContainerW(ref DsBrowseInfo info);

    public const int DSBI_ENTIREDIRECTORY = 0x00090000;
    public const int ADS_FORMAT_WINDOWS = 1;
    public enum BrowseStatus
        BrowseError = -1,
        BrowseOk = 1,
        BrowseCancel = 2

class App
    // Must be marked as STA because the default is MTA. 
    // DsBrowseForContainerW calls CoInitialize, which initializes the 
    // COM library as STA.
    public static void Main()
        DsBrowseInfo dsbi = new DsBrowseInfo();

        dsbi.Size = Marshal.SizeOf(typeof(DsBrowseInfo));
        dsbi.PathSize = DsBrowseInfo.MAX_PATH;
        dsbi.Caption = "Container Selection Example";
        dsbi.Title = "Select a container from the list.";
        dsbi.ReturnFormat = LibWrap.ADS_FORMAT_WINDOWS;
        dsbi.Flags = LibWrap.DSBI_ENTIREDIRECTORY;
        dsbi.Root = "LDAP:";
        dsbi.Path = new string(new char[DsBrowseInfo.MAX_PATH]);
        // Initialize remaining members... 

        int status = LibWrap.DsBrowseForContainerW(ref dsbi);
        if ((LibWrap.BrowseStatus)status == LibWrap.BrowseStatus.BrowseOk)
            Console.WriteLine("No path returned.");
Was this page helpful?
(1500 characters remaining)
Thank you for your feedback
© 2014 Microsoft