コード例 #1
0
        /// <summary>
        /// Executes an Android Sdk tool and returns a result. The result is based on a function of the command output.
        /// </summary>
        public static Task <TResult> ExecuteToolAsync <TResult> (string exe, Func <string, TResult> result, CancellationToken token, Action <Process>?onStarted = null)
        {
            var tcs = new TaskCompletionSource <TResult> ();

            var log   = new StringWriter();
            var error = new StringWriter();

            var psi = new ProcessStartInfo(exe);

            psi.CreateNoWindow        = true;
            psi.RedirectStandardInput = onStarted != null;

            var processTask = ProcessUtils.StartProcess(psi, log, error, token, onStarted);
            var exeName     = Path.GetFileName(exe);

            processTask.ContinueWith(t => {
                var output      = log.ToString();
                var errorOutput = error.ToString();
                log.Dispose();
                error.Dispose();

                if (t.IsCanceled)
                {
                    tcs.TrySetCanceled();
                    return;
                }

                if (t.IsFaulted)
                {
                    tcs.TrySetException(t.Exception?.Flatten()?.InnerException ?? t.Exception !);
                    return;
                }

                if (t.Result == 0)
                {
                    tcs.TrySetResult(result != null ? result(output) : default(TResult) !);
                }
                else
                {
                    var errorMessage = !string.IsNullOrEmpty(errorOutput) ? errorOutput : output;
                    errorMessage     = string.IsNullOrEmpty(errorMessage)
                                                ? $"`{exeName}` returned non-zero exit code"
                                                : $"{t.Result} : {errorMessage}";

                    tcs.TrySetException(new InvalidOperationException(errorMessage));
                }
            }, TaskContinuationOptions.ExecuteSynchronously);

            return(tcs.Task);
        }
コード例 #2
0
        void FixOwnership(List <string>?paths)
        {
            if (!need_chown || paths == null || paths.Count == 0)
            {
                return;
            }

            var stdout = new StringWriter();
            var stderr = new StringWriter();
            var args   = new List <string> {
                QuoteString(sudo_user !)
            };

            foreach (string p in paths)
            {
                args.Add(QuoteString(p));
            }

            var psi = new ProcessStartInfo(OS.IsMac ? "/usr/sbin/chown" : "/bin/chown")
            {
                CreateNoWindow = true,
                Arguments      = String.Join(" ", args),
            };

            Logger(TraceLevel.Verbose, $"Changing filesystem object ownership: {psi.FileName} {psi.Arguments}");
            Task <int> chown_task = ProcessUtils.StartProcess(psi, stdout, stderr, System.Threading.CancellationToken.None);

            if (chown_task.Result != 0)
            {
                Logger(TraceLevel.Warning, $"Failed to change ownership of filesystem object(s)");
                Logger(TraceLevel.Verbose, $"standard output: {stdout}");
                Logger(TraceLevel.Verbose, $"standard error: {stderr}");
            }

            string QuoteString(string p)
            {
                return($"\"{p}\"");
            }
        }
    }