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 .NET clients are initialized as STA objects and do not need to be adjusted. The Microsoft .NET Framework SDK includes the complete Visual Basic .NET and C# versions of this sample in Samples\Technologies\Interop\Platform-Invoke.

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 .NET clients, no attribute is required. The Marshal.SizeOf method dynamically calculates the size of the unmanaged structure.

Declaring Prototypes

Public Class LibWrap
   ' Declares a managed prototype for the unmanaged function.
   Declare Unicode Function DsBrowseForContainerW Lib "dsuiext.dll" ( _
      ByRef info As DSBrowseInfo ) As Integer
   Public Shared DSBI_ENTIREDIRECTORY As Integer = &H90000
End Class 'LibWrap
[C#]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;   
}

Calling Functions

Class App
   Public Shared MAX_PATH As Integer = 256
   ' The DsBrowseForContainerW method should be called from STA.
   ' STA is the default for Visual Basic .NET clients, so no explicit
   ' setting is required as it is for C# clients.
   Public Shared Sub Main()
      ' Initializes all members.
      Dim dsbi As New DSBrowseInfo()
      
      Dim status As Integer = LibWrap.DsBrowseForContainerW( dsbi )
   End Sub 'Main
   
End Class 'App
[C#]class App
{
   public const int MAX_PATH = 256;
   // Must be marked as STA because the default is MTA. 
   // DsBrowseForContainerW calls CoInitialize, which initializes the 
   // COM library as STA.
   [ STAThread ]
   public static void Main()
   {
      // Initializes all members.
      ...
      int status = LibWrap.DsBrowseForContainerW( ref dsbi );
   }
}

See Also

Miscellaneous Marshaling Samples | Platform Invoke Data Types | Creating Prototypes in Managed Code