Generate user token which can directly use in CreateProcessAsUser C# fuction

This C# function take the username and ref to token as an arguments and retunrs a true if valid token has been assigned to token variable that can be directly use in the CreateProcessAsUser function. Please download and add the reference of WtsApi32.dll from

You can call GenerateUserToken function which will create valid security token that you can use as a handle to token in below PInvoke type function CreateProcessAsUser(For more details about this function see

[DllImport("advapi32.dll", SetLastError=true, CharSet=CharSet.Auto)]
static extern bool CreateProcessAsUser(
    IntPtr hToken,
    string lpApplicationName,
    [In] StringBuilder lpCommandLine,
    ref SECURITY_ATTRIBUTES lpProcessAttributes,
    ref SECURITY_ATTRIBUTES lpThreadAttributes,
    bool bInheritHandles,
    uint dwCreationFlags,
    IntPtr lpEnvironment,
    string lpCurrentDirectory,
    ref STARTUPINFO lpStartupInfo,
    out PROCESS_INFORMATION lpProcessInformation);           

C# Function to get the valid security token:

        /// <summary>
        ///        Retrieves the logon token for the user that is
        ///        logged into the computer with a user name that is
        ///        equal to the parameter userName.
        /// </summary>
        /// <param name="userName">
        ///        User name to get token for.
        /// </param>
        /// <param name="userToken">
        ///        User logon token.
        /// </param>
        /// <returns>
        ///        True if the token was retrieved, otherwise false.
        /// </returns>
        private bool GenerateUserToken(string userName, ref IntPtr userToken)
            // open a handle to the localhost
            IntPtr hSvr = WtsApi32.Native.WtsOpenServer(null);

            // get a list of the sessions on the localhost
            WtsApi32.WtsSessionInfo[] wsis;
                wsis = WtsApi32.Managed.WtsEnumerateSessions(hSvr);
            catch (Win32Exception e)
                return (false);

            // check all the sessions on the server to get the logon token
            // of the user that has the same user name as the userName parameter
            for (int x = 0; x < wsis.Length && userToken == IntPtr.Zero; ++x)
                // declare 2 strings to hold the user name and domain name
                string un = string.Empty, dn = string.Empty;

                // compare the session's user name with the userName
                // parameter and get the logon token if they are equal
                if (WtsApi32.Managed.WtsQuerySessionInformation(
                        hSvr, wsis[x].SessionId,
                        out un)


                        hSvr, wsis[x].SessionId,
                        out dn)


                    ((dn.ToLower() + "\\" + un.ToLower()) == userName.ToLower()))
                    WtsApi32.Native.WtsQueryUserToken(wsis[x].SessionId, ref userToken);

            if (hSvr != IntPtr.Zero)

            return (userToken != IntPtr.Zero);

By Perry    Popularity  (4385 Views)