LoadUserProfile is responsible for loading the profile data (%USERPROFILE%, etc) used by environment args and by System.Environment.GetSpecialFolder().

Execution requires SE_BACKUP_NAME and SE_RESTORE_NAME permissions.

Implements IDisposable to ensure that the profile and tokens are released from memory.

NOTE: while the API includes a parameter for any users' token, this code will always assume the current users' token. A constructor parameter for a WindowsIdentity could be used to load another users' token.
Code Snippet

public static class UserEnv


    public class LoadedUserProfile : IDisposable


        private PROFILEINFO _profileInfo;

        public LoadedUserProfile()


            var currentIdentity = System.Security.Principal.WindowsIdentity.GetCurrent();


            // prepare _profileInfo for use by LoadUserProfile

            _profileInfo = new PROFILEINFO()


                dwSize = Marshal.SizeOf(typeof(PROFILEINFO)),

                lpUserName = currentIdentity.Name.Split('\\').Last(),

                dwFlags = (int)PROFILEINFO__FLAGS.PI_NOUI



            var result = LoadUserProfile(currentIdentity.Token, ref _profileInfo);

            if (!result)


                var err = Kernel32.GetLastError();

                throw new System.ComponentModel.Win32Exception(err);




        public void Dispose()


            UnloadUserProfile(System.Security.Principal.WindowsIdentity.GetCurrent().Token, _profileInfo.hProfile);


    } // class LoadedUserProfile



    #region Private - Interop code


    [DllImport("userenv.dll", SetLastError = true, CharSet = CharSet.Auto)]

    static extern bool LoadUserProfile(IntPtr hToken, ref PROFILEINFO lpProfileInfo);


    [DllImport("userenv.dll", SetLastError = true, CharSet = CharSet.Auto)]

    static extern bool UnloadUserProfile(IntPtr hToken, IntPtr hProfile);



    struct PROFILEINFO


        public int dwSize;

        public int dwFlags;


        public String lpUserName;


        public String lpProfilePath;


        public String lpDefaultPath;


        public String lpServerName;


        public String lpPolicyPath;

        public IntPtr hProfile;




    private enum PROFILEINFO__FLAGS : int


        /// <summary>

        /// Prevents the display of profile error messages.

        /// </summary>

        PI_NOUI = 0x00000001



    //private const Int32 PI_NOUI = 0x00000001;


} // class


// LoadedUserProfile calls interop APIs to load environment settings for the current user

using (new Interop.UserEnv.LoadedUserProfile())

    // do something here

} // using LoadedUserProfile

Created 2013-04-22
comments powered by Disqus