private void CreateServerProcessWorker(Func <IEnumerable <string> > preCreate, Action <CreateProcessResult> postCreate)
        {
            Logger.LogInfo("Creating VsChromiumHost process.");
            var path = GetProcessPath();

            Logger.LogInfo("  Path={0}", path);
            var serverPath = Path.Combine(Path.GetDirectoryName(path.Value), ServerName);

            Logger.LogInfo("  Server path={0}", serverPath);

            var arguments = new List <string>();

            arguments.Add(serverPath);
            arguments.AddRange(preCreate());
#if PROFILE_SERVER
            arguments.Add("/profile-server");
#endif

            var argumentLine = arguments.Aggregate("", (x, v) => x + QuoteArgument(v) + " ");
            Logger.LogInfo("  Arguments={0}", argumentLine);
            _serverProcess = _processCreator.CreateProcess(path.Value, argumentLine,
                                                           CreateProcessOptions.AttachDebugger |
                                                           CreateProcessOptions.BreakAwayFromJob);
            Logger.LogInfo("VsChromiumHost process created (pid={0}).", _serverProcess.Process.Id);
            postCreate(_serverProcess);
        }
        /// <summary>
        /// Note: Calls are serialized by _serverProcessLauncher, so no need to lock
        /// </summary>
        private void AfterProxyCreated(CreateProcessResult serverProcess)
        {
            Logger.LogInfo("AfterProxyCreated (pid={0}", serverProcess.Process.Id);
#if PROFILE_SERVER
            var timeout = TimeSpan.FromSeconds(120.0);
            System.Diagnostics.Trace.WriteLine(string.Format("You have {0:n0} seconds to start the server process with a port argument of {1}.", timeout.TotalSeconds, ((IPEndPoint)_tcpListener.LocalEndpoint).Port));
#else
            var timeout = TimeSpan.FromSeconds(5.0);
#endif
            Logger.LogInfo("AfterProxyCreated: Wait for TCP client connection from server process.");
            if (!_waitForConnection.WaitOne(timeout))
            {
                throw new InvalidOperationException(
                          string.Format("Child process did not connect to server within {0:n0} seconds.", timeout.TotalSeconds));
            }

            _ipcStream = new IpcStreamOverNetworkStream(_serializer, _tcpClient.GetStream());

            // Ensure process is alive and ready to process requests
            Logger.LogInfo("AfterProxyCreated: Wait for \"Hello\" message from server process.");
            WaitForProcessHelloMessage();

            // Start reading process output
            Logger.LogInfo("AfterProxyCreated: Start receive response thread.");
            _receiveResponsesThread.ResponseReceived += response => {
                var callback = _callbacks.Remove(response.RequestId);
                callback(response);
            };
            _receiveResponsesThread.EventReceived += @event => { OnEventReceived(@event); };
            _receiveResponsesThread.Start(_ipcStream);

            Logger.LogInfo("AfterProxyCreated: Start send request thread..");
            _sendRequestsThread.RequestError += OnRequestError;
            _sendRequestsThread.Start(_ipcStream, _requestQueue);
        }
Example #3
0
        public Task <CreateProcessResult> ExecuteAsync(CreateProcessParams p)
        {
            var runSpec = new ProcessRunSpec
            {
                ExecutablePath   = p.executablePath,
                Arguments        = p.arguments,
                Environment      = p.environment,
                WorkingDirectory = p.workingDirectory,
                OutputCallback   = (data) =>
                {
                    processTracker.HandleProcessData(p.key, ProcessDataType.STDOUT, data);
                },
                ErrorCallback = (data) =>
                {
                    processTracker.HandleProcessData(p.key, ProcessDataType.STDERR, data);
                },
            };

            var process = processRunner.Run(runSpec);

            processTracker.TrackProcess(p.key, process);

            var result = new CreateProcessResult
            {
                id = process.Id,
            };

            return(Task.FromResult(result));
        }
        public Task<CreateProcessResult> ExecuteAsync(CreateProcessParams p)
        {
            var runSpec = new ProcessRunSpec
            {
                ExecutablePath = p.executablePath,
                Arguments = p.arguments,
                Environment = p.environment,
                WorkingDirectory = p.workingDirectory,
                OutputCallback = (data) =>
                {
                    processTracker.HandleProcessData(p.key, ProcessDataType.STDOUT, data);
                },
                ErrorCallback = (data) =>
                {
                    processTracker.HandleProcessData(p.key, ProcessDataType.STDERR, data);
                },
            };

            var process = processRunner.Run(runSpec);

            processTracker.TrackProcess(p.key, process);

            var result = new CreateProcessResult
            {
                id = process.Id,
            };

            return Task.FromResult(result);
        }
            public CreateProcess()
            {
                ExpectedResult   = new CreateProcessResult();
                ExpectedResponse = new CreateProcessResponse(JToken.FromObject(1), ExpectedResult);

                MessagingClient.SendMessageAsync <CreateProcessRequest, CreateProcessResponse>(null)
                .ReturnsForAnyArgs(GetCompletedTask(ExpectedResponse));
            }
            private void HandleError(ProcessStartInfo psi, CreateProcessResult returnValue)
            {
                switch (returnValue)
                {
                case CreateProcessResult.AccessDenied:
                case CreateProcessResult.InsufficientPrivilege:
                    Command.ErrorHandler.WriteFileError(psi.FileName, new UnauthorizedAccessException());
                    break;

                case CreateProcessResult.PathNotFound:
                    Command.ErrorHandler.WriteFileNotFoundError(psi.FileName);
                    break;

                case CreateProcessResult.UnknownFailure:
                default:
                    string message = string.Format(Properties.Resources.StartProcessFailed, psi.FileName, _scope.Path.Server);
                    Command.ErrorHandler.WriteProcessFailedToStart(null, new Exception(message));
                    break;
                }
            }
            private Process CreateProcess(ProcessStartInfo psi)
            {
                ManagementClass      win32_Process = GetClass(_scope, "Win32_Process");
                ManagementBaseObject inParams      = win32_Process.GetMethodParameters("Create");

                inParams["CommandLine"] = BuildCommandLine(psi.FileName, psi.Arguments);
                inParams["ProcessStartupInformation"] = CreateProcessStartup(psi);

                if (Command._workingDirSpecified)
                {
                    inParams["CurrentDirectory"] = psi.WorkingDirectory;
                }

                ManagementBaseObject outParams = win32_Process.InvokeMethod("Create", inParams,
                                                                            new InvokeMethodOptions());

                CreateProcessResult returnValue = (CreateProcessResult)(uint)outParams["ReturnValue"];

                if (returnValue == CreateProcessResult.Success)
                {
                    int     processId = unchecked ((int)(uint)outParams["ProcessId"]);
                    Process process   = null;

                    try
                    {
                        process = Process.GetProcessById(processId, _scope.Path.Server);
                    }
                    catch (ArgumentException)
                    {
                        Command.WriteWarning(string.Format(Properties.Resources.StartProcessExitedTooSoon, processId));
                    }

                    return(process);
                }
                else
                {
                    HandleError(psi, returnValue);
                }

                return(null);
            }
        private void AfterProxyCreated(CreateProcessResult processResult)
        {
            Invariants.Assert(processResult != null);

            Logger.LogInfo("AfterProxyCreated (pid={0}", processResult.Process.Id);
#if PROFILE_SERVER
            var timeout = TimeSpan.FromSeconds(120.0);
            System.Diagnostics.Trace.WriteLine(string.Format(
                                                   "You have {0:n0} seconds to start the server process with a port argument of {1}.", timeout.TotalSeconds,
                                                   ((IPEndPoint)_tcpListener.LocalEndpoint).Port));
#else
            var timeout = TimeSpan.FromSeconds(30.0);
#endif
            Logger.LogInfo("AfterProxyCreated: Wait for TCP client connection from server process.");
            var serverStartedSuccessfully = _waitForConnection.WaitOne(timeout) && _tcpClient != null;
            Invariants.CheckOperation(serverStartedSuccessfully, $"Child process did not connect to server within {timeout.TotalSeconds:n0} seconds.");

            _ipcStream = new IpcStreamOverNetworkStream(_serializer, _tcpClient.GetStream());

            // Ensure process is alive and ready to process requests
            Logger.LogInfo("AfterProxyCreated: Wait for \"Hello\" message from server process.");
            WaitForProcessHelloMessage();

            // Start reading process output
            Logger.LogInfo("AfterProxyCreated: Start receive response thread.");
            _receiveResponsesThread.ResponseReceived += response => {
                var callback = _callbacks.Remove(response.RequestId);
                callback(response);
            };
            _receiveResponsesThread.EventReceived += @event => { OnEventReceived(@event); };
            _receiveResponsesThread.FatalError    += (sender, args) => { HandleReceiveThreadFatalError(args); };
            _receiveResponsesThread.Start(_ipcStream);

            Logger.LogInfo("AfterProxyCreated: Start send request thread..");
            _sendRequestsThread.SendRequestError += HandleSendRequestError;
            _sendRequestsThread.Start(_ipcStream, _requestQueue);

            // Server is fully started, notify consumers
            _isServerRunning = true;
            OnProcessStarted();
        }
            private void HandleError(ProcessStartInfo psi, CreateProcessResult returnValue)
            {
                switch (returnValue)
                {
                    case CreateProcessResult.AccessDenied:
                    case CreateProcessResult.InsufficientPrivilege:
                        Command.ErrorHandler.WriteFileError(psi.FileName, new UnauthorizedAccessException());
                        break;

                    case CreateProcessResult.PathNotFound:
                        Command.ErrorHandler.WriteFileNotFoundError(psi.FileName);
                        break;

                    case CreateProcessResult.UnknownFailure:
                    default:
                        string message = string.Format(Properties.Resources.StartProcessFailed, psi.FileName, _scope.Path.Server);
                        Command.ErrorHandler.WriteProcessFailedToStart(null, new Exception(message));
                        break;

                }
            }