예제 #1
0
        /// <summary>
        /// Starts a process resource by specifying the name of an application and a set of command-line arguments.
        /// </summary>
        /// <param name="processContext">The process context of an application file to run in the process.</param>
        /// <param name="processCompletedCallback">The process completed callback, invoked only when the process is started successfully and completed.</param>
        /// <exception cref="ArgumentNullException">The <paramref name="processContext"/> is <c>null</c>.</exception>
        /// <exception cref="Win32Exception">An error occurred when opening the associated file.</exception>
        public virtual void StartProcess(ProcessContext processContext, ProcessCompletedDelegate processCompletedCallback = null)
        {
            var task = RunAsync(processContext);

            if (processCompletedCallback != null)
            {
                task.ContinueWith(x => processCompletedCallback(task.Result.ExitCode));
            }
        }
예제 #2
0
        /// <summary>
        /// Starts a process and returns an awaitable task which will end once the application is closed.
        /// </summary>
        /// <param name="processContext">The process context of an application file to run in the process.</param>
        /// <returns>The <see cref="ProcessResult"/> containing details about the execution.</returns>
        /// <exception cref="ArgumentNullException">The <paramref name="processContext"/> is <c>null</c>.</exception>
        public virtual async Task <ProcessResult> RunAsync(ProcessContext processContext)
        {
            Argument.IsNotNull(nameof(processContext), processContext);
            Argument.IsNotNullOrWhitespace(nameof(processContext.FileName), processContext.FileName);

            var fileName = processContext.FileName;

            var arguments = processContext.Arguments;

            if (arguments == null)
            {
                arguments = string.Empty;
            }

            var tcs = new TaskCompletionSource <int>();

            Log.Debug($"Running '{processContext.FileName}'");

            try
            {
#if NETFX_CORE
                var launcher = Launcher.LaunchUriAsync(new Uri(fileName));
                if (processCompletedCallback != null)
                {
                    launcher.Completed += (sender, e) => tcs.SetResult(0);
                }
#else
                var processStartInfo = new ProcessStartInfo(fileName, arguments)
                {
                    Verb = processContext.Verb
                };

                if (!string.IsNullOrWhiteSpace(processContext.WorkingDirectory))
                {
                    processStartInfo.WorkingDirectory = processContext.WorkingDirectory;
                }

                var process = Process.Start(processStartInfo);
                process.EnableRaisingEvents = true;
                process.Exited += (sender, e) => tcs.SetResult(process.ExitCode);
#endif
            }
            catch (Exception ex)
            {
                Log.Error(ex, $"An error occurred while running '{processContext.FileName}'");

                tcs.SetException(ex);
            }

            await tcs.Task;

            return(new ProcessResult(processContext)
            {
                ExitCode = tcs.Task.Result
            });
        }
예제 #3
0
        /// <summary>
        /// Starts a process and returns an awaitable task which will end once the application is closed.
        /// </summary>
        /// <param name="processContext">The process context of an application file to run in the process.</param>
        /// <returns>The <see cref="ProcessResult"/> containing details about the execution.</returns>
        /// <exception cref="ArgumentNullException">The <paramref name="processContext"/> is <c>null</c>.</exception>
        public virtual async Task <ProcessResult> RunAsync(ProcessContext processContext)
        {
            Argument.IsNotNull(nameof(processContext), processContext);
            Argument.IsNotNullOrWhitespace(nameof(processContext.FileName), processContext.FileName);

            var fileName = processContext.FileName;

            var arguments = processContext.Arguments;

            if (arguments is null)
            {
                arguments = string.Empty;
            }

            var tcs = new TaskCompletionSource <int>();

            Log.Debug($"Running '{processContext.FileName}'");

            try
            {
#if UWP
                await Launcher.LaunchUriAsync(new Uri(fileName));
#else
                var processStartInfo = new ProcessStartInfo(fileName, arguments)
                {
                    Verb            = processContext.Verb,
                    UseShellExecute = processContext.UseShellExecute
                };

                // Note for debuggers: whenever you *inspect* processStartInfo *and* use UseShellExecute = true,
                // the debugger will evaluate the Environment and EnvironmentVariables properties and instantiate them.
                // This will result in Process.Start to throw exceptions. The solution is *not* to inspect processStartInfo
                // when UseShellExecute is true

                if (!string.IsNullOrWhiteSpace(processContext.Verb) &&
                    !processStartInfo.UseShellExecute)
                {
                    Log.Warning($"Verb is specified, this requires UseShellExecute to be set to true");

                    processStartInfo.UseShellExecute = true;
                }

                if (!string.IsNullOrWhiteSpace(processContext.WorkingDirectory))
                {
                    processStartInfo.WorkingDirectory = processContext.WorkingDirectory;
                }

                var process = Process.Start(processStartInfo);
                if (process is null)
                {
                    Log.Debug($"Process is already completed, cannot wait for it to complete");

                    tcs.SetResult(0);
                }
                else
                {
                    process.EnableRaisingEvents = true;
                    process.Exited += (sender, e) => tcs.SetResult(process.ExitCode);
                }
#endif
            }
            catch (Exception ex)
            {
                Log.Error(ex, $"An error occurred while running '{processContext.FileName}'");

                tcs.SetException(ex);
            }

            await tcs.Task;

            return(new ProcessResult(processContext)
            {
                ExitCode = tcs.Task?.Result ?? 0
            });
        }