/// <summary>
        /// Creates a RemoteSessionNamedPipeServer with the current process and AppDomain information.
        /// </summary>
        /// <returns>RemoteSessionNamedPipeServer</returns>
        public static RemoteSessionNamedPipeServer CreateRemoteSessionNamedPipeServer()
        {
            string appDomainName = NamedPipeUtils.GetCurrentAppDomainName();

            return(new RemoteSessionNamedPipeServer(NamedPipeUtils.CreateProcessPipeName(
                                                        System.Diagnostics.Process.GetCurrentProcess(), appDomainName)));
        }
        /// <summary>
        /// Constructor. Creates Named Pipe based on process Id, app domain name and container object root path.
        /// </summary>
        /// <param name="procId">Target process Id for pipe.</param>
        /// <param name="appDomainName">AppDomain name or null for default AppDomain</param>
        /// <param name="containerObRoot">Container OB root.</param>
        public ContainerSessionNamedPipeClient(
            int procId,
            string appDomainName,
            string containerObRoot)
        {
            if (String.IsNullOrEmpty(containerObRoot))
            {
                throw new PSArgumentNullException("containerObRoot");
            }

            //
            // Named pipe inside Windows Server container is under different name space.
            //
            _pipeName = containerObRoot + @"\Device\NamedPipe\" +
                        NamedPipeUtils.CreateProcessPipeName(procId, appDomainName);
        }
        private void ProcessListeningThread(object state)
        {
            string processId     = System.Diagnostics.Process.GetCurrentProcess().Id.ToString(CultureInfo.InvariantCulture);
            string appDomainName = NamedPipeUtils.GetCurrentAppDomainName();

            // Logging.
            _tracer.WriteMessage("RemoteSessionNamedPipeServer", "StartListening", Guid.Empty,
                                 "Listener thread started on Process {0} in AppDomainName {1}.", processId, appDomainName);
            PSEtwLog.LogOperationalInformation(
                PSEventId.NamedPipeIPC_ServerListenerStarted, PSOpcode.Open, PSTask.NamedPipe,
                PSKeyword.UseAlwaysOperational,
                processId, appDomainName);

            Exception ex       = null;
            string    userName = string.Empty;
            bool      restartListenerThread = true;

            // Wait for connection.
            try
            {
                // Begin listening for a client connect.
                this.WaitForConnection();

                try
                {
                    userName = WindowsIdentity.GetCurrent().Name;
                }
                catch (System.Security.SecurityException) { }

                // Logging.
                _tracer.WriteMessage("RemoteSessionNamedPipeServer", "StartListening", Guid.Empty,
                                     "Client connection started on Process {0} in AppDomainName {1} for User {2}.", processId, appDomainName, userName);
                PSEtwLog.LogOperationalInformation(
                    PSEventId.NamedPipeIPC_ServerConnect, PSOpcode.Connect, PSTask.NamedPipe,
                    PSKeyword.UseAlwaysOperational,
                    processId, appDomainName, userName);

                // Create reader/writer streams.
                TextReader           = new StreamReader(Stream);
                TextWriter           = new StreamWriter(Stream);
                TextWriter.AutoFlush = true;
            }
            catch (Exception e)
            {
                CommandProcessorBase.CheckForSevereException(e);
                ex = e;
            }
            if (ex != null)
            {
                // Error during connection handling.  Don't try to restart listening thread.
                string errorMessage = !string.IsNullOrEmpty(ex.Message) ? ex.Message : string.Empty;
                _tracer.WriteMessage("RemoteSessionNamedPipeServer", "StartListening", Guid.Empty,
                                     "Unexpected error in listener thread on process {0} in AppDomainName {1}.  Error Message: {2}", processId, appDomainName, errorMessage);
                PSEtwLog.LogOperationalError(PSEventId.NamedPipeIPC_ServerListenerError, PSOpcode.Exception, PSTask.NamedPipe,
                                             PSKeyword.UseAlwaysOperational,
                                             processId, appDomainName, errorMessage);

                Dispose();
                return;
            }

            // Start server session on new connection.
            ex = null;
            try
            {
                Action <RemoteSessionNamedPipeServer> clientConnectCallback = state as Action <RemoteSessionNamedPipeServer>;
                Dbg.Assert(clientConnectCallback != null, "Client callback should never be null.");

                // Handle a new client connect by making the callback.
                // The callback must handle all exceptions except
                // for a named pipe disposed or disconnected exception
                // which propagates up to the thread listener loop.
                clientConnectCallback(this);
            }
            catch (IOException)
            {
                // Expected connection terminated.
            }
            catch (ObjectDisposedException)
            {
                // Expected from PS transport close/dispose.
            }
            catch (Exception e)
            {
                CommandProcessorBase.CheckForSevereException(e);
                ex = e;
                restartListenerThread = false;
            }

            // Logging.
            _tracer.WriteMessage("RemoteSessionNamedPipeServer", "StartListening", Guid.Empty,
                                 "Client connection ended on process {0} in AppDomainName {1} for User {2}.", processId, appDomainName, userName);
            PSEtwLog.LogOperationalInformation(
                PSEventId.NamedPipeIPC_ServerDisconnect, PSOpcode.Close, PSTask.NamedPipe,
                PSKeyword.UseAlwaysOperational,
                processId, appDomainName, userName);

            if (ex == null)
            {
                // Normal listener exit.
                _tracer.WriteMessage("RemoteSessionNamedPipeServer", "StartListening", Guid.Empty,
                                     "Listener thread ended on process {0} in AppDomainName {1}.", processId, appDomainName);
                PSEtwLog.LogOperationalInformation(PSEventId.NamedPipeIPC_ServerListenerEnded, PSOpcode.Close, PSTask.NamedPipe,
                                                   PSKeyword.UseAlwaysOperational,
                                                   processId, appDomainName);
            }
            else
            {
                // Unexpected error.
                string errorMessage = !string.IsNullOrEmpty(ex.Message) ? ex.Message : string.Empty;
                _tracer.WriteMessage("RemoteSessionNamedPipeServer", "StartListening", Guid.Empty,
                                     "Unexpected error in listener thread on process {0} in AppDomainName {1}.  Error Message: {2}", processId, appDomainName, errorMessage);
                PSEtwLog.LogOperationalError(PSEventId.NamedPipeIPC_ServerListenerError, PSOpcode.Exception, PSTask.NamedPipe,
                                             PSKeyword.UseAlwaysOperational,
                                             processId, appDomainName, errorMessage);
            }

            lock (_syncObject)
            {
                IsListenerRunning = false;
            }

            // Ensure this named pipe server object is disposed.
            Dispose();

            ListenerEnded.SafeInvoke(
                this,
                new ListenerEndedEventArgs(ex, restartListenerThread));
        }
 /// <summary>
 /// Constructor. Creates Named Pipe based on process Id.
 /// </summary>
 /// <param name="procId">Target process Id for pipe.</param>
 /// <param name="appDomainName">AppDomain name or null for default AppDomain</param>
 public RemoteSessionNamedPipeClient(
     int procId, string appDomainName) :
     this(NamedPipeUtils.CreateProcessPipeName(procId, appDomainName))
 {
 }
 /// <summary>
 /// Constructor.  Creates Named Pipe based on process object.
 /// </summary>
 /// <param name="process">Target process object for pipe.</param>
 /// <param name="appDomainName">AppDomain name or null for default AppDomain</param>
 public RemoteSessionNamedPipeClient(
     System.Diagnostics.Process process, string appDomainName) :
     this(NamedPipeUtils.CreateProcessPipeName(process, appDomainName))
 {
 }