private void WaitForConnectionCallBack(IAsyncResult iar)
        {
            try
            {
                // Get the pipe
                var pipeServer = (NamedPipeServerStream)iar.AsyncState;
                // End waiting for the connection
                pipeServer.EndWaitForConnection(iar);

                var bRequest = new byte[1024];
                do
                {
                    int cbRequest = bRequest.Length;
                    pipeServer.Read(bRequest, 0, cbRequest);
                }
                while (!pipeServer.IsMessageComplete);

                var serializer = new XmlSerializer(typeof(StartInfo));
                var startInfo = (StartInfo)serializer.Deserialize(new MemoryStream(bRequest));

                NativeMethods.EnableSecurityRights("SeTcbPrivilege", true);
                NativeMethods.EnableSecurityRights("SeAssignPrimaryTokenPrivilege", true);
                NativeMethods.EnableSecurityRights("SeIncreaseQuotaPrivilege", true);

                pipeServer.RunAsClient(() =>
                {
                    PROCESS_INFORMATION procInfo;
                    var startupInfo = new STARTUPINFO();

                    int size = Marshal.SizeOf(startupInfo);
                    startupInfo.cb = size;

                    if (startInfo.Interact)
                    {
                        //TODO: Find right session ID and call SetTokenInformation to set it to the user token

                        startupInfo.dwFlags = 0x00000001; //#define STARTF_USESHOWWINDOW
                        startupInfo.wShowWindow = 5; //#define SW_SHOW
                        startupInfo.lpDesktop = "WinSta0\\Default";
                    }

                    if (!CreateProcessAsUser(WindowsIdentity.GetCurrent().Token, null, startInfo.CommandLine, IntPtr.Zero, IntPtr.Zero, false, 0, IntPtr.Zero, null, ref startupInfo, out procInfo))
                    {
                        Debug.WriteLine(String.Format("{0}", Marshal.GetLastWin32Error()));
                    }
                });

                // Kill original sever and create new wait server
                pipeServer.Close();
                pipeServer = new NamedPipeServerStream(_pipeName, PipeDirection.In,
                   1, PipeTransmissionMode.Message, PipeOptions.Asynchronous, 1024, 1024, _security);

                // Recursively wait for the connection again and again....
                pipeServer.BeginWaitForConnection(
                   WaitForConnectionCallBack, pipeServer);
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
        }
 static extern bool CreateProcessAsUser(
     IntPtr hToken,
     string lpApplicationName,
     string lpCommandLine,
     IntPtr lpProcessAttributes,
     IntPtr lpThreadAttributes,
     bool bInheritHandles,
     uint dwCreationFlags,
     IntPtr lpEnvironment,
     string lpCurrentDirectory,
     ref STARTUPINFO lpStartupInfo,
     out PROCESS_INFORMATION lpProcessInformation);