First - so I don't get in any trouble - I've posted a similar question on other forums but have not gotten any responses so branching out in my quest for help as well as changing the question a little.

Previously I was trying to find out why calling LoadUserProfile(...) was not creating the User Profile if it did not already exist (for example when creating an account programmatically) - MSDN had the following article on HOW TO but it doesn't seem to work (copy/paste the code and switched it to C# - account is created, no failures or exceptions, but User Profile is just not created)
http://support.microsoft.com/kb/196070/en-us

Now, forget this as I assume it just isn't the right approach (or just doesn't work anymore - hopefully not me making a stupid mistake)

Anyways - my question is - what other means can I use to programmatically create a USER PROFILE for a user account?
Is there some kind of CreateUserProfile(...) function (I couldn't find one on MSDN), etc...

Any help would be much appreciated...
Thanks,

Recommended Answers

All 23 Replies

Sadly not that I can see - this is all about creating and managing the accounts and does not touch on the User Profiles themselves.
But thanks - good source of information.

I'm not sure you can invoke the creation of the new user's profile without logging the user onto the system, which is when a new user's profile gets created (logging in for the first time).

Have you tried LogonUser (advapi32.dll) and Impersonation? See: Windows Impersonation. I have my doubts, but if you have not tried it yet you might give it shot.

Sadly yes I have tried both and neither create the profile (impersonation itself doesn't create a user profile, nor does LogonUser) - actually the only place I have ever seen mention that you can is in that MSDN article but it doesn't seem to work on my system (copy/paste the sample code).

Thanks,

What OS are you testing that LoadUserProfile call on?

I have tested with both Windows 2000 pro and Windows XP SP2

OK, I ran this code on my XP laptop and it did create the profile. However, when I went to look under documents and settings, the username I expected to see was cryptic looking (3 vertical rect chars?)--I don't know what you call those chars but you see them all the time if you open a binary file in notepad.

Anyway, take a look at it and let me know also if it worked and what's up with how it created my user's folder name as mentioned above. It is initiated by calling static method: WindowsLoadUserProfile.Test()

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Principal;

namespace ForumSolutions
{

    public class WindowsLoadUserProfile
    {
        /// 
        /// The LogonUser function attempts to log a user on to the local computer.
        /// 
        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern bool LogonUser(String lpszUsername, String lpszDomain, IntPtr lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr hToken);

        /// 
        /// The DuplicateTokenEx function creates a new access token that duplicates an existing token. This function can create either a primary token or an impersonation token.
        /// 
        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern bool DuplicateTokenEx(IntPtr hExistingToken, int dwDesiredAccess, ref SecurityAttributes lpTokenAttributes,
        int impersonationLevel, int tokenType, out IntPtr phNewToken);

        /// 
        /// The LoadUserProfile function loads the specified user's profile
        /// 
        [DllImport("userenv.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern bool LoadUserProfile(IntPtr hToken, ref ProfileInfo lpProfileInfo);

        /// 
        /// The UnloadUserProfile function unloads a user's profile that was loaded by the LoadUserProfile function
        /// 
        [DllImport("userenv.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern bool UnloadUserProfile(IntPtr hToken, IntPtr hProfile);

        /// 
        /// Closes an open object handle.
        /// 
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern bool CloseHandle(IntPtr handle);

        /// 
        /// The SECURITY_ATTRIBUTES structure contains the security descriptor for an object and specifies whether the handle retrieved by specifying this structure is inheritable
        /// 
        [StructLayout(LayoutKind.Sequential)]
        public struct SecurityAttributes
        {
            public int dwLength;
            public IntPtr lpSecurityDescriptor;
            public bool bInheritHandle;
        }

        /// 
        /// Profile Info
        /// 
        [StructLayout(LayoutKind.Sequential)]
        public struct ProfileInfo
        {
            /// 
            /// Specifies the size of the structure, in bytes.
            /// 
            public int dwSize;

            /// 
            /// This member can be one of the following flags: PI_NOUI or PI_APPLYPOLICY
            /// 
            public int dwFlags;

            /// 
            /// Pointer to the name of the user. 
            /// This member is used as the base name of the directory in which to store a new profile. 
            /// 
            public string lpUserName;

            /// 
            /// Pointer to the roaming user profile path. 
            /// If the user does not have a roaming profile, this member can be NULL.
            /// 
            public string lpProfilePath;

            /// 
            /// Pointer to the default user profile path. This member can be NULL. 
            /// 
            public string lpDefaultPath;

            /// 
            /// Pointer to the name of the validating domain controller, in NetBIOS format. 
            /// If this member is NULL, the Windows NT 4.0-style policy will not be applied. 
            /// 
            public string lpServerName;

            /// 
            /// Pointer to the path of the Windows NT 4.0-style policy file. This member can be NULL. 
            /// 
            public string lpPolicyPath;

            /// 
            /// Handle to the HKEY_CURRENT_USER registry key. 
            /// 
            public IntPtr hProfile;
        }        /// 
        /// Logon type option. 
        /// 
        [FlagsAttribute]
        public enum LogonType
        {
            /// 
            /// This logon type is intended for users who will be interactively using the computer
            /// 
            Interactive = 2,
            /// 
            /// This logon type is intended for high performance servers to authenticate plaintext passwords. 
            /// 
            Network = 3,
            /// 
            /// This logon type is intended for batch servers, where processes may be executing on behalf of a user without their direct intervention.
            /// 
            Batch = 4,
            /// 
            /// Indicates a service-type logon. The account provided must have the service privilege enabled.
            /// 
            Service = 5,
            /// 
            /// This logon type is for GINA DLLs that log on users who will be interactively using the computer.
            /// 
            Unlock = 7
        }
        /// 
        /// Specifies the logon provider. 
        /// 
        [FlagsAttribute]
        public enum LogonProvider
        {
            /// 
            /// Use the standard logon provider for the system.
            /// 
            Default = 0,
            /// 
            /// Use the negotiate logon provider. (WINNT50)
            /// 
            Negotiate = 3,
            /// 
            /// Use the NTLM logon provider (WINNT40)
            /// 
            NTLM = 2,
            /// 
            /// Use the Windows NT 3.5 logon provider.
            /// 
            WinNT35 = 1
        }
        /// 
        /// Specifies the requested access rights for the new token.
        /// 
        [FlagsAttribute]
        public enum DuplicateTokenDesiredAccess
        {
            /// 
            /// To request the same access rights as the existing token, specify zero. 
            /// 
            SameAsExisting = 0,
            /// 
            /// To request all access rights that are valid for the caller, specify MAXIMUM_ALLOWED.
            /// 
            MaximumAllowed = 0x02000000
        }
        /// 
        /// Specifies a value from the SECURITY_IMPERSONATION_LEVEL enumeration that indicates the impersonation level of the new token 
        /// 
        [FlagsAttribute]
        public enum ImpersonationLevel
        {
            /// 
            /// The server process cannot obtain identification information about the client, and it cannot impersonate the client. It is defined with no value given, and thus, by ANSI C rules, defaults to a value of zero.
            /// 
            Anonymous = 0,
            /// 
            /// The server process can obtain information about the client, such as security identifiers and privileges, but it cannot impersonate the client. This is useful for servers that export their own objects, for example, database products that export tables and views. Using the retrieved client-security information, the server can make access-validation decisions without being able to use other services that are using the client's security context.,
            /// 
            Identification = 1,
            /// 
            /// The server process can impersonate the client's security context on its local system. The server cannot impersonate the client on remote systems.,
            /// 
            Impersonation = 2,
            /// 
            /// The server process can impersonate the client's security context on remote systems. This impersonation level is not supported on WinNT
            /// 
            Delegation = 3
        }
        /// 
        /// Specifies the requested access rights for the new token.
        /// 
        [FlagsAttribute]
        public enum TokenType
        {
            /// 
            /// The new token is a primary token that you can use in the CreateProcessAsUser function. 
            /// 
            Primary = 1,
            /// 
            /// The new token is an impersonation token. 
            /// 
            Impersonation = 2
        }

        public static void Test()
        {
            WindowsLoadUserProfile wu = new WindowsLoadUserProfile();

            try
            {
                // already created user with cmd: net user testuser testpwd /ADD

                wu.LogonUser("testuser", System.Environment.MachineName, "testpwd",
                    LogonType.Network, LogonProvider.Default);

                wu.LoadUserProfile("testuser"); // create user's profile if not exist

                wu.LogOffUser();
            }
            catch (Exception ex)
            {
                System.Text.StringBuilder sb = new System.Text.StringBuilder();
                while (ex != null)
                {
                    sb.AppendLine("Message: " + ex.Message);
                    sb.AppendLine("Source: " + ex.Source);
                    sb.AppendLine("Stack: ");
                    sb.AppendLine(ex.StackTrace);
                    ex = ex.InnerException;
                }
                Console.WriteLine(sb.ToString());
                if (System.Diagnostics.Debugger.IsAttached)
                    System.Diagnostics.Debugger.Break();
            }
        }

        IntPtr hToken = new IntPtr(0);
        IntPtr hProfile = new IntPtr(0);

        private void LogonUser(String user, String domain, /*SecureString password*/ String password, LogonType type, LogonProvider provider)
        {
#if false
            if (password.IsReadOnly() == false)
                throw new InvalidOperationException("SecureString not ReadOnly");
#endif
            if (string.IsNullOrEmpty(user) == true || string.IsNullOrEmpty(domain) == true)
                throw new InvalidOperationException("No user account specified");

            IntPtr handle;
            
            //IntPtr bstr = Marshal.SecureStringToBSTR(password);
            IntPtr bstr = Marshal.StringToHGlobalUni(password);

            bool result = LogonUser(user, domain, bstr, (int)type, (int)provider, out handle);
            
            //Marshal.ZeroFreeBSTR(bstr);
            Marshal.FreeHGlobal(bstr);

            if (result == false)
                throw new System.ComponentModel.Win32Exception();

            SecurityAttributes sa = new SecurityAttributes();
            sa.dwLength = Marshal.SizeOf(sa);
            sa.lpSecurityDescriptor = IntPtr.Zero;
            sa.bInheritHandle = true;

            IntPtr newHandle;
            result = DuplicateTokenEx(handle, (int)DuplicateTokenDesiredAccess.MaximumAllowed, ref sa,
            (int)ImpersonationLevel.Impersonation, (int)TokenType.Primary, out newHandle);
            if (result == false)
                throw new System.ComponentModel.Win32Exception();

            CloseHandle(handle);
            handle = newHandle;

            hToken = handle;
        }

        public void LoadUserProfile(string username)
        {
            if (hToken == IntPtr.Zero)
                throw new InvalidOperationException("User not logged in");

            ProfileInfo info = new ProfileInfo();
            info.dwSize = Marshal.SizeOf(info);
            info.lpUserName = username;
            info.dwFlags = 1; // PI_NOUI 0x00000001 // Prevents displaying of messages

            bool result = LoadUserProfile(hToken, ref info);
            if (result == false)
                throw new System.ComponentModel.Win32Exception();

            hProfile = info.hProfile;
        }

        internal void LogOffUser()
        {
#if false
string identity = WindowsIdentity.GetCurrent().Name;
string threadIdentity = Thread.CurrentPrincipal.Identity.Name;
scriptTask.State.AddMessage(DateTime.Now, string.Format("Logging off user {0} ({1})", identity, threadIdentity));
#endif

            WindowsIdentity.Impersonate(IntPtr.Zero);

#if false
identity = WindowsIdentity.GetCurrent().Name;
Thread.CurrentPrincipal = new WindowsPrincipal(WindowsIdentity.GetCurrent());
threadIdentity = Thread.CurrentPrincipal.Identity.Name;
scriptTask.State.AddMessage(DateTime.Now, string.Format("Identity now {0} ({1})", identity, threadIdentity));
#endif

            if (hToken != IntPtr.Zero && hProfile != IntPtr.Zero)
            {
                bool result = UnloadUserProfile(hToken, hProfile);
                hProfile = IntPtr.Zero;

                if (result == false)
                    throw new System.ComponentModel.Win32Exception();
            }

            if (hToken != IntPtr.Zero)
            {
                bool result = CloseHandle(hToken);
                hToken = IntPtr.Zero;

                if (result == false)
                    throw new System.ComponentModel.Win32Exception();
            }

        }
    }
}

Wow - that fixed my first problem all right - I wasn't setting up LogonUser properly (forgot to convert to (int) some of the ENUM parameters).

Now the Profile is created but just like you said I get the odd squares (invalid windows characters) - not sure why but it is a problem as Windows actually re-creates a correct one when logged-on.

So close - if you figure it out let me know - I'll be working on it also at this end and if I find the reason I'll post back.

Thanks a lot ...

You didn't marshal all the strings:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Principal;

namespace daniweb
{

  public class WindowsLoadUserProfile
  {
    /// 
    /// The LogonUser function attempts to log a user on to the local computer.
    /// 
    [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern bool LogonUser([MarshalAs(UnmanagedType.LPStr)] String lpszUsername, [MarshalAs(UnmanagedType.LPStr)] String lpszDomain, IntPtr lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr hToken);

    /// 
    /// The DuplicateTokenEx function creates a new access token that duplicates an existing token. This function can create either a primary token or an impersonation token.
    /// 
    [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern bool DuplicateTokenEx(IntPtr hExistingToken, int dwDesiredAccess, ref SecurityAttributes lpTokenAttributes,
    int impersonationLevel, int tokenType, out IntPtr phNewToken);

    /// 
    /// The LoadUserProfile function loads the specified user's profile
    /// 
    [DllImport("userenv.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern bool LoadUserProfile(IntPtr hToken, ref ProfileInfo lpProfileInfo);

    /// 
    /// The UnloadUserProfile function unloads a user's profile that was loaded by the LoadUserProfile function
    /// 
    [DllImport("userenv.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern bool UnloadUserProfile(IntPtr hToken, IntPtr hProfile);

    /// 
    /// Closes an open object handle.
    /// 
    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern bool CloseHandle(IntPtr handle);

    /// 
    /// The SECURITY_ATTRIBUTES structure contains the security descriptor for an object and specifies whether the handle retrieved by specifying this structure is inheritable
    /// 
    [StructLayout(LayoutKind.Sequential)]
    public struct SecurityAttributes
    {
      public int dwLength;
      public IntPtr lpSecurityDescriptor;
      public bool bInheritHandle;
    }

    /// 
    /// Profile Info
    /// 
    [StructLayout(LayoutKind.Sequential)]
    public struct ProfileInfo
    {
      /// 
      /// Specifies the size of the structure, in bytes.
      /// 
      public int dwSize;

      /// 
      /// This member can be one of the following flags: PI_NOUI or PI_APPLYPOLICY
      /// 
      public int dwFlags;

      /// 
      /// Pointer to the name of the user. 
      /// This member is used as the base name of the directory in which to store a new profile. 
      /// 
      [MarshalAs(UnmanagedType.LPTStr)]
      public string lpUserName;

      /// 
      /// Pointer to the roaming user profile path. 
      /// If the user does not have a roaming profile, this member can be NULL.
      /// 
      [MarshalAs(UnmanagedType.LPStr)]
      public string lpProfilePath;

      /// 
      /// Pointer to the default user profile path. This member can be NULL. 
      /// 
      [MarshalAs(UnmanagedType.LPStr)]
      public string lpDefaultPath;

      /// 
      /// Pointer to the name of the validating domain controller, in NetBIOS format. 
      /// If this member is NULL, the Windows NT 4.0-style policy will not be applied. 
      /// 
      [MarshalAs(UnmanagedType.LPStr)]
      public string lpServerName;

      /// 
      /// Pointer to the path of the Windows NT 4.0-style policy file. This member can be NULL. 
      /// 
      [MarshalAs(UnmanagedType.LPStr)]
      public string lpPolicyPath;

      /// 
      /// Handle to the HKEY_CURRENT_USER registry key. 
      /// 
      public IntPtr hProfile;
    }        /// 
    /// Logon type option. 
    /// 
    [FlagsAttribute]
    public enum LogonType
    {
      /// 
      /// This logon type is intended for users who will be interactively using the computer
      /// 
      Interactive = 2,
      /// 
      /// This logon type is intended for high performance servers to authenticate plaintext passwords. 
      /// 
      Network = 3,
      /// 
      /// This logon type is intended for batch servers, where processes may be executing on behalf of a user without their direct intervention.
      /// 
      Batch = 4,
      /// 
      /// Indicates a service-type logon. The account provided must have the service privilege enabled.
      /// 
      Service = 5,
      /// 
      /// This logon type is for GINA DLLs that log on users who will be interactively using the computer.
      /// 
      Unlock = 7
    }
    /// 
    /// Specifies the logon provider. 
    /// 
    [FlagsAttribute]
    public enum LogonProvider
    {
      /// 
      /// Use the standard logon provider for the system.
      /// 
      Default = 0,
      /// 
      /// Use the negotiate logon provider. (WINNT50)
      /// 
      Negotiate = 3,
      /// 
      /// Use the NTLM logon provider (WINNT40)
      /// 
      NTLM = 2,
      /// 
      /// Use the Windows NT 3.5 logon provider.
      /// 
      WinNT35 = 1
    }
    /// 
    /// Specifies the requested access rights for the new token.
    /// 
    [FlagsAttribute]
    public enum DuplicateTokenDesiredAccess
    {
      /// 
      /// To request the same access rights as the existing token, specify zero. 
      /// 
      SameAsExisting = 0,
      /// 
      /// To request all access rights that are valid for the caller, specify MAXIMUM_ALLOWED.
      /// 
      MaximumAllowed = 0x02000000
    }
    /// 
    /// Specifies a value from the SECURITY_IMPERSONATION_LEVEL enumeration that indicates the impersonation level of the new token 
    /// 
    [FlagsAttribute]
    public enum ImpersonationLevel
    {
      /// 
      /// The server process cannot obtain identification information about the client, and it cannot impersonate the client. It is defined with no value given, and thus, by ANSI C rules, defaults to a value of zero.
      /// 
      Anonymous = 0,
      /// 
      /// The server process can obtain information about the client, such as security identifiers and privileges, but it cannot impersonate the client. This is useful for servers that export their own objects, for example, database products that export tables and views. Using the retrieved client-security information, the server can make access-validation decisions without being able to use other services that are using the client's security context.,
      /// 
      Identification = 1,
      /// 
      /// The server process can impersonate the client's security context on its local system. The server cannot impersonate the client on remote systems.,
      /// 
      Impersonation = 2,
      /// 
      /// The server process can impersonate the client's security context on remote systems. This impersonation level is not supported on WinNT
      /// 
      Delegation = 3
    }
    /// 
    /// Specifies the requested access rights for the new token.
    /// 
    [FlagsAttribute]
    public enum TokenType
    {
      /// 
      /// The new token is a primary token that you can use in the CreateProcessAsUser function. 
      /// 
      Primary = 1,
      /// 
      /// The new token is an impersonation token. 
      /// 
      Impersonation = 2
    }

    public static void Test()
    {
      WindowsLoadUserProfile wu = new WindowsLoadUserProfile();
      
      try
      {
        // already created user with cmd: net user testuser testpwd /ADD

        wu.LogonUser("testuser", System.Environment.MachineName, "testpwd",
            LogonType.Network, LogonProvider.Default);

        wu.LoadUserProfile("testuser"); // create user's profile if not exist

        wu.LogOffUser();
      }
      catch (Exception ex)
      {
        System.Text.StringBuilder sb = new System.Text.StringBuilder();
        while (ex != null)
        {
          sb.AppendLine("Message: " + ex.Message);
          sb.AppendLine("Source: " + ex.Source);
          sb.AppendLine("Stack: ");
          sb.AppendLine(ex.StackTrace);
          ex = ex.InnerException;
        }
        Console.WriteLine(sb.ToString());
        if (System.Diagnostics.Debugger.IsAttached)
          System.Diagnostics.Debugger.Break();
      }
    }

    IntPtr hToken = new IntPtr(0);
    IntPtr hProfile = new IntPtr(0);

    private void LogonUser(String user, String domain, /*SecureString password*/ String password, LogonType type, LogonProvider provider)
    {
#if false
            if (password.IsReadOnly() == false)
                throw new InvalidOperationException("SecureString not ReadOnly");
#endif
      if (string.IsNullOrEmpty(user) == true || string.IsNullOrEmpty(domain) == true)
        throw new InvalidOperationException("No user account specified");

      IntPtr handle;

      //IntPtr bstr = Marshal.SecureStringToBSTR(password);
      IntPtr bstr = Marshal.StringToHGlobalUni(password);

      bool result = LogonUser(user, domain, bstr, (int)type, (int)provider, out handle);

      //Marshal.ZeroFreeBSTR(bstr);
      Marshal.FreeHGlobal(bstr);

      if (result == false)
        throw new System.ComponentModel.Win32Exception();

      SecurityAttributes sa = new SecurityAttributes();
      sa.dwLength = Marshal.SizeOf(sa);
      sa.lpSecurityDescriptor = IntPtr.Zero;
      sa.bInheritHandle = true;

      IntPtr newHandle;
      result = DuplicateTokenEx(handle, (int)DuplicateTokenDesiredAccess.MaximumAllowed, ref sa,
      (int)ImpersonationLevel.Impersonation, (int)TokenType.Primary, out newHandle);
      if (result == false)
        throw new System.ComponentModel.Win32Exception();

      CloseHandle(handle);
      handle = newHandle;

      hToken = handle;
    }

    public void LoadUserProfile(string username)
    {
      if (hToken == IntPtr.Zero)
        throw new InvalidOperationException("User not logged in");
      
      ProfileInfo info = new ProfileInfo();
      info.dwSize = Marshal.SizeOf(info);
      info.lpUserName = username;
      info.dwFlags = 1; // PI_NOUI 0x00000001 // Prevents displaying of messages

      bool result = LoadUserProfile(hToken, ref info);
      if (result == false)
        throw new System.ComponentModel.Win32Exception();

      hProfile = info.hProfile;
    }

    internal void LogOffUser()
    {
#if false
string identity = WindowsIdentity.GetCurrent().Name;
string threadIdentity = Thread.CurrentPrincipal.Identity.Name;
scriptTask.State.AddMessage(DateTime.Now, string.Format("Logging off user {0} ({1})", identity, threadIdentity));
#endif

      WindowsIdentity.Impersonate(IntPtr.Zero);

#if false
identity = WindowsIdentity.GetCurrent().Name;
Thread.CurrentPrincipal = new WindowsPrincipal(WindowsIdentity.GetCurrent());
threadIdentity = Thread.CurrentPrincipal.Identity.Name;
scriptTask.State.AddMessage(DateTime.Now, string.Format("Identity now {0} ({1})", identity, threadIdentity));
#endif

      if (hToken != IntPtr.Zero && hProfile != IntPtr.Zero)
      {
        bool result = UnloadUserProfile(hToken, hProfile);
        hProfile = IntPtr.Zero;

        if (result == false)
          throw new System.ComponentModel.Win32Exception();
      }

      if (hToken != IntPtr.Zero)
      {
        bool result = CloseHandle(hToken);
        hToken = IntPtr.Zero;

        if (result == false)
          throw new System.ComponentModel.Win32Exception();
      }

    }
  }
}

That should create the profiles properly

That fixed the immediate problem of having to set the name without the illegal characters (great) - but it seems to have introduced something else.

The account is created fine, as is the user profile - but now subsequent calls to LogonUser(string, string, intptr, ...) fail with invalid username & pasword - do I need to do some funky Marshal/Unmarshal conversion to the username, domain, and password for it to work now that LogonUser has changed?

If I remove all the Marshalling added LogonUser works fine ...

DdoubleD: why do you only set the Password to IntPtr and do the Marshling? Why not username and domain also?

DdoubleD: why do you only set the Password to IntPtr and do the Marshling? Why not username and domain also?

Because of this prototype declaration I found (see below). It's possible that it is incorrect because I just pulled it off the web and not from MSDN, which we know is always correct too--LOL.

Anyway, after really thinking about it, I doubt seriously that prototype is correct using "String" in a Win32 API call. Also, look at the variable naming convention: lpsz, or long pointer to null-terminated string (long pointer to null terminated char array in C/CPP; aka char*).

The answer is near though...

/// 
        /// The LogonUser function attempts to log a user on to the local computer.
        /// 
        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern bool LogonUser(String lpszUsername, String lpszDomain, IntPtr lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr hToken);

From what I can see LogonUser takes an LP**T**STR, not an LPSTR, as parameters. You should just use the default string marshaling, and it will work correctly. See LogonUser and pinvoke.net's declaration for a property P/Invoke of LogonUser.

But this causes the odd unrecoginized square characters when creating the profile (LoadUserProfile) ... lol ... no way to win? :)

Ooooooh Scott, come on man, I know you know the answer... ;) Help us out please?

Well - wasn't able to figure out why but there is a difference between NETWORK and INTERACTIVE logon type, if you use INTERACTIVE and do not include any of the marshaling then everything works perfectly fine - and that is what I needed ...

You have both provided me with a LOT of help - thank you very much ... Let me know if you figure out why it is different when using the NETWORK login type.

Well - wasn't able to figure out why but there is a difference between NETWORK and INTERACTIVE logon type, if you use INTERACTIVE and do not include any of the marshaling then everything works perfectly fine - and that is what I needed ...

You have both provided me with a LOT of help - thank you very much ... Let me know if you figure out why it is different when using the NETWORK login type.

Not sure why it is different, but I can tell you why I used NETWORK. The MS link indicated it was best:

// Do a network logon because most systems do not grant new users
      // the right to logon interactively (SE_INTERACTIVE_LOGON_NAME)
      // but they do grant the right to do a network logon
      // (SE_NETWORK_LOGON_NAME). A network logon has the added advantage
      // of being quicker.

Did you get it working?

I have a hunch that there is a problem with that. After I ran that code I started noticing odd behavior on my machine. I closed winamp and when I re-opened it all of a sudden my playlist was different.

Then I started noticing websites where I have my password stored, like daniweb, required me to log in again. I was thinking 'wtf'

Then I tried to reboot my machine:

The attempt to rebootSCOTTIE failed

For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp.
The attempt to power off SCOTTIE failed

For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp.

That being said it I think that code screws up who windows think the logged on user is. The *only* thing that worked was logging off which then finally allowed me to reboot and since then everything has seemed ok. Review the code for something changing the active user. If you can't find anything then let me know and I will take a look at it.

Its a very long piece of code and i'm in the middle of a project right now :(

[edit]
The NETWORK vs. INTERACTIVE might have been the issue. It might have switched the INTERACTIVE logged on profile (me) to that user profile that I created. I deleted the profile directory in C:\Document and Settings\ right after I created it, which may be why the browser cookies etc couldn't save.
[/edit]

Did you get it working?

I have a hunch that there is a problem with that. After I ran that code I started noticing odd behavior on my machine. I closed winamp and when I re-opened it all of a sudden my playlist was different.

Then I started noticing websites where I have my password stored, like daniweb, required me to log in again. I was thinking 'wtf'

Then I tried to reboot my machine:

The attempt to rebootSCOTTIE failed

For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp.
The attempt to power off SCOTTIE failed

For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp.

That being said it I think that code screws up who windows think the logged on user is. The *only* thing that worked was logging off which then finally allowed me to reboot and since then everything has seemed ok. Review the code for something changing the active user. If you can't find anything then let me know and I will take a look at it.

Its a very long piece of code and i'm in the middle of a project right now :(

[edit]
The NETWORK vs. INTERACTIVE might have been the issue. It might have switched the INTERACTIVE logged on profile (me) to that user profile that I created. I deleted the profile directory in C:\Document and Settings\ right after I created it, which may be why the browser cookies etc couldn't save.
[/edit]

LOL - My sympathies too. I didn't have any trouble except for what I initially reported, but I only ran the code once that I submitted and none of the proposed changes. Several hours later I simply shutdown all my apps, deleted the new user, rebooted, then deleted the document folder.

LOL - My sympathies too. I didn't have any trouble except for what I initially reported, but I only ran the code once that I submitted and none of the proposed changes. Several hours later I simply shutdown all my apps, deleted the new user, rebooted, then deleted the document folder.

:D ...still laughing...

I would like to suggest keeping this thread alive until all of the "minor" issues, :D, have been resolved, then posting a final solution so others can benefit.;)

Yeah ... I hope whoever ventures across this thread reads all the way to the end too :)

Article pretty usefull, it was exactly what I was looking for... I had an idea how to create a user profile, but this clarified some of my doubts

I ran above code but LogonUser() returning with false.what would be the problem?

commented: Windows changed over the years. You may have to research new ways and create new code. Also, why not a batch file? +15
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.