예제 #1
0
        /// <summary>
        /// Invoked when the debug host is loading. By default this launches the remote service client.
        /// </summary>
        protected virtual void DebugHostLoading()
        {
            // Start remote console session
            string serviceClientName = ServiceClientName;

            if (!string.IsNullOrWhiteSpace(serviceClientName))
            {
                m_processManager = new ChildProcessManager();
                m_processManager.AddProcess(Process.Start(FilePath.GetAbsolutePath(serviceClientName)));
            }
        }
예제 #2
0
        /// <summary>
        /// Initializes <see cref="ProcessLauncher"/>.
        /// </summary>
        public override void Initialize()
        {
            base.Initialize();

            Dictionary <string, string> settings = Settings;
            ProcessWindowStyle          windowStyle;
            int    initialInputProcessingDelay, utilizationCalculationInterval;
            string setting;

            ProcessStartInfo startInfo = m_process.StartInfo;

            // Load required parameters
            if (settings.TryGetValue(nameof(FileName), out setting))
            {
                setting = FilePath.GetAbsolutePath(setting.Trim());

                if (File.Exists(setting))
                {
                    FileName           = setting;
                    startInfo.FileName = FileName;
                }
                else
                {
                    throw new FileNotFoundException($"Cannot launch process: specified executable path and filename \"{setting}\" does not exist.");
                }
            }
            else
            {
                throw new ArgumentException($"Cannot launch process: required \"{nameof(FileName)}\" parameter is missing from connection string.");
            }

            // Load optional parameters
            if (settings.TryGetValue(nameof(SupportsTemporalProcessing), out setting))
            {
                m_supportsTemporalProcessing = setting.ParseBoolean();
            }
            else
            {
                m_supportsTemporalProcessing = DefaultSupportsTemporalProcessing;
            }

            if (settings.TryGetValue(nameof(Arguments), out setting) && setting.Length > 0)
            {
                startInfo.Arguments = setting;
            }

            if (settings.TryGetValue(nameof(WorkingDirectory), out setting))
            {
                setting = setting.Trim();

                if (Directory.Exists(setting))
                {
                    WorkingDirectory           = setting;
                    startInfo.WorkingDirectory = WorkingDirectory;
                }
                else
                {
                    throw new DirectoryNotFoundException($"Cannot launch process: specified working directory \"{setting}\" does not exist.");
                }
            }
            else
            {
                WorkingDirectory           = FilePath.GetDirectoryName(FileName);
                startInfo.WorkingDirectory = WorkingDirectory;
            }

            if (settings.TryGetValue(nameof(EnvironmentalVariables), out setting))
            {
                foreach (KeyValuePair <string, string> item in setting.ParseKeyValuePairs())
                {
                    startInfo.Environment[item.Key] = item.Value;
                }
            }

            // Note that it's possible that time-series framework is being hosted by an application
            // running in a Window making many of the following process start properties relevant.
            // Even when hosted as a service, the user may start the service logging on using the
            // local system account and select to allow the service interact with the desktop.
            if (settings.TryGetValue(nameof(CreateNoWindow), out setting))
            {
                startInfo.CreateNoWindow = setting.ParseBoolean();
            }
            else
            {
                startInfo.CreateNoWindow = DefaultCreateNoWindow;
            }

            if (settings.TryGetValue(nameof(WindowStyle), out setting) && Enum.TryParse(setting, true, out windowStyle))
            {
                startInfo.WindowStyle = windowStyle;
            }
            else
            {
                startInfo.WindowStyle = (ProcessWindowStyle)Enum.Parse(typeof(ProcessWindowStyle), DefaultWindowStyle);
            }

            if (settings.TryGetValue(nameof(ErrorDialog), out setting))
            {
                startInfo.ErrorDialog = setting.ParseBoolean();
            }
            else
            {
                startInfo.ErrorDialog = DefaultErrorDialog;
            }

            if (settings.TryGetValue(nameof(Domain), out setting) && setting.Length > 0)
            {
                startInfo.Domain = setting;
            }

            if (settings.TryGetValue(nameof(UserName), out setting) && setting.Length > 0)
            {
                startInfo.UserName = setting;
            }

            if (settings.TryGetValue(nameof(Password), out setting) && setting.Length > 0)
            {
                startInfo.Password = setting.ToSecureString();
            }

            if (settings.TryGetValue(nameof(LoadUserProfile), out setting))
            {
                startInfo.LoadUserProfile = setting.ParseBoolean();
            }

            if (settings.TryGetValue(nameof(InitialInputFileName), out setting))
            {
                setting = FilePath.GetAbsolutePath(setting.Trim());

                if (File.Exists(setting))
                {
                    InitialInputFileName = setting;
                }
                else
                {
                    throw new FileNotFoundException($"Cannot launch process: specified initial input filename \"{setting}\" does not exist.");
                }
            }

            if (settings.TryGetValue(nameof(InitialInputProcessingDelay), out setting) && int.TryParse(setting, out initialInputProcessingDelay) && initialInputProcessingDelay > -1)
            {
                InitialInputProcessingDelay = initialInputProcessingDelay;
            }

            if (settings.TryGetValue(nameof(RedirectOutputToHostEnvironment), out setting))
            {
                RedirectOutputToHostEnvironment = setting.ParseBoolean();
            }

            if (settings.TryGetValue(nameof(RedirectErrorToHostEnvironment), out setting))
            {
                RedirectErrorToHostEnvironment = setting.ParseBoolean();
            }

            if (settings.TryGetValue(nameof(UtilizationUpdateInterval), out setting) && int.TryParse(setting, out utilizationCalculationInterval))
            {
                UtilizationUpdateInterval = utilizationCalculationInterval;
            }

            startInfo.RedirectStandardOutput = RedirectOutputToHostEnvironment;
            startInfo.RedirectStandardError  = RedirectErrorToHostEnvironment;
            startInfo.RedirectStandardInput  = true;
            startInfo.UseShellExecute        = false;

            m_process.EnableRaisingEvents = true;
            m_process.OutputDataReceived += ProcessOutputDataReceived;
            m_process.ErrorDataReceived  += ProcessErrorDataReceived;

            if (settings.TryGetValue(nameof(ProcessOutputAsLogMessages), out setting))
            {
                ProcessOutputAsLogMessages = setting.ParseBoolean();
            }

            if (ProcessOutputAsLogMessages)
            {
                if (settings.TryGetValue(nameof(LogMessageTextExpression), out setting) && setting.Length > 0)
                {
                    LogMessageTextExpression = setting;
                }

                m_logMessageTextExpression = new Regex(LogMessageTextExpression, RegexOptions.Compiled);

                if (settings.TryGetValue(nameof(LogMessageLevelExpression), out setting) && setting.Length > 0)
                {
                    LogMessageLevelExpression = setting;
                }

                m_logMessageLevelExpression = new Regex(LogMessageLevelExpression, RegexOptions.Compiled);

                if (settings.TryGetValue(nameof(LogMessageLevelMappings), out setting))
                {
                    LogMessageLevelMappings = setting;
                }

                foreach (KeyValuePair <string, string> item in LogMessageLevelMappings.ParseKeyValuePairs())
                {
                    MessageLevel level;

                    if (Enum.TryParse(item.Value, true, out level))
                    {
                        m_messageLevelMap[item.Key] = level;
                    }
                }
            }

            if (settings.TryGetValue(nameof(ForceKillOnDispose), out setting))
            {
                ForceKillOnDispose = setting.ParseBoolean();
            }

            if (settings.TryGetValue(nameof(TrackProcessStatistics), out setting))
            {
                TrackProcessStatistics = setting.ParseBoolean();
            }

            m_process.Start();

            if (ForceKillOnDispose)
            {
                m_childProcessManager?.AddProcess(m_process);
            }

            if (RedirectOutputToHostEnvironment)
            {
                m_process.BeginOutputReadLine();
            }

            if (RedirectErrorToHostEnvironment)
            {
                m_process.BeginErrorReadLine();
            }

            m_processUtilizationCalculator.UpdateInterval = UtilizationUpdateInterval;
            m_processUtilizationCalculator.Initialize(m_process);

            // Register launched process with the statistics engine
            if (TrackProcessStatistics)
            {
                StatisticsEngine.Register(this, "Process", "PROC");
            }

            if (string.IsNullOrEmpty(InitialInputFileName))
            {
                return;
            }

            // Send any defined initial input to launched application
            new Action(() =>
            {
                try
                {
                    using (StreamReader reader = File.OpenText(InitialInputFileName))
                    {
                        string line;

                        while ((object)(line = reader.ReadLine()) != null)
                        {
                            Input(line);
                        }
                    }
                }
                catch (Exception ex)
                {
                    OnProcessException(MessageLevel.Warning, new InvalidOperationException($"Failed while sending text from \"{InitialInputFileName}\" to launched process standard input: {ex.Message}", ex));
                }
            })
            .DelayAndExecute(InitialInputProcessingDelay);
        }