Search code examples
c#namespacesusing

Can I use NetUserGetInfo in C#?


I want to use http://msdn.microsoft.com/en-us/library/aa370654%28VS.85%29.aspx in my code. But for some reason I cannot find what namespace to use for it. Three that I thought would work are

using System.DirectoryServices.AccountManagement;
using System.Runtime.InteropServices;
using System.DirectoryServices;

But none of these work. All of the examples of using NetUserGetInfo I can find are in C++, rather than C#. That makes me think that maybe I cannot use it in C#. Can I? And if so, what namespace I should use to have access to the NetUserGetInfo function? Any help is appreciated.


Solution

  • What namespace are you looking for? Namespaces are .NET specific notions. The NetUserGetInfo is a Win32 unmanaged function. If you want to invoke it from managed .NET code you need to write a managed wrapper and call it through P/Invoke.

    Here's a useful site in this case which illustrates the following managed wrapper:

    [DllImport("Netapi32.dll", CharSet=CharSet.Unicode, ExactSpelling=true)]
    private extern static int NetUserGetInfo(
        [MarshalAs(UnmanagedType.LPWStr)] string ServerName,
        [MarshalAs(UnmanagedType.LPWStr)] string UserName, 
        int level, 
        out IntPtr BufPtr
    );
    

    A user defined structure:

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct USER_INFO_10
    {
        [MarshalAs(UnmanagedType.LPWStr)]
        public string usri10_name;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string usri10_comment;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string usri10_usr_comment;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string usri10_full_name;
    }
    

    and a sample invocation:

    public bool AccountGetFullName(string MachineName, string AccountName, ref string FullName) 
    {
        if (MachineName.Length == 0 ) 
        {
            throw new ArgumentException("Machine Name is required");
        }
        if (AccountName.Length == 0 ) 
        {
            throw new ArgumentException("Account Name is required");
        }
        try 
        {
            // Create an new instance of the USER_INFO_1 struct
            USER_INFO_10 objUserInfo10 = new USER_INFO_10();
            IntPtr bufPtr; // because it's an OUT, we don't need to Alloc
            int lngReturn = NetUserGetInfo(MachineName, AccountName, 10, out bufPtr ) ;
            if (lngReturn == 0) 
            {
                objUserInfo10 = (USER_INFO_10) Marshal.PtrToStructure(bufPtr, typeof(USER_INFO_10) );
                FullName = objUserInfo10.usri10_full_name;
            }
            NetApiBufferFree( bufPtr );
            bufPtr = IntPtr.Zero;
            if (lngReturn == 0 ) 
            {
                return true;
            }
            else 
            {
                //throw new System.ApplicationException("Could not get user's Full Name.");
                return false;
            }
        } 
        catch (Exception exp)
        {
            Debug.WriteLine("AccountGetFullName: " + exp.Message);
            return false;
        }
    }