public int Run()
        {
            STARTUPINFO si = new STARTUPINFO();
            si.lpDesktop = Desktop;
            PROCESSINFO pi = new PROCESSINFO();

            int creationFlags = NORMAL_PRIORITY_CLASS | CREATE_UNICODE_ENVIRONMENT;
            creationFlags |= CreateNoWindow ? CREATE_NO_WINDOW : 0;

            //This creates the default environment block for this user. If you need
            //something custom skip te CreateEnvironmentBlock (and DestroyEnvironmentBlock)
            //calls. You need to handle the allocation of the memory and writing to
            //it yourself.
            IntPtr envBlock;
            if (!CreateEnvironmentBlock(out envBlock, m_SessionTokenHandle, 0))
            {
                throw new System.ComponentModel.Win32Exception();
            }

            try
            {
                if (!CreateProcessAsUser(m_SessionTokenHandle, m_ApplicationPath, CommandLine, IntPtr.Zero,
                    IntPtr.Zero, 0, creationFlags, envBlock, WorkingDirectory,
                    si, pi))
                {
                    throw new System.ComponentModel.Win32Exception();
                }
            }
            finally
            {
                DestroyEnvironmentBlock(envBlock);
            }

            CloseHandle(pi.hThread);
            CloseHandle(pi.hProcess);

            return pi.dwProcessId;
        }
 private static extern bool CreateProcessAsUser(IntPtr hToken, string lpApplicationName,
     string lpCommandLine, IntPtr lpProcessAttributes, IntPtr lpThreadAttributes,
     int bInheritHandles, int dwCreationFlags, IntPtr lpEnvironment,
     string lpCurrentDirectory, STARTUPINFO lpStartupInfo, 
     [Out]PROCESSINFO lpProcessInformation);