Пример #1
0
        public async Task <int> ExcuteAsync(
            string workingDir,
            string fileName,
            string args,
            ConcurrentQueue <string> inputs     = null,
            bool killProcessOnCancel            = true,
            CancellationToken cancellationToken = default)
        {
            InitProcess(workingDir, fileName, args, killProcessOnCancel);

            // Ensure we process STDOUT even the process exit event happen before we start read STDOUT stream.
            Interlocked.Increment(ref _streamReadCount);
            Interlocked.Increment(ref _streamReadCount);

            _stopWatch = Stopwatch.StartNew();

            _proc.Start();

            var readErrorTask = ReadStream(_proc.StandardError, _errorData);

            var readOutputTask = ReadStream(_proc.StandardOutput, _outputData);

            if (inputs != null)
            {
                var task = WriteStream(inputs, _proc.StandardInput, true);
            }
            else
            {
                // Close the input stream. This is done to prevent commands from blocking the build waiting for input from the user.
                _proc.StandardInput.Close();
            }

            using (var registration = cancellationToken.Register(async() => await CancelAndKillProcessTree(killProcessOnCancel)))
            {
                _trace?.Verbose($"Process started with process id {_proc.Id}, waiting for process exit.");

                while (true)
                {
                    Task outputSignal = _outputProcessEvent.WaitAsync();

                    var signaled = await Task.WhenAny(outputSignal, _processExitedCompletionSource.Task);

                    if (signaled == outputSignal)
                    {
                        ProcessOutput();
                    }
                    else
                    {
                        _stopWatch.Stop();
                        break;
                    }
                }

                ProcessOutput();

                _trace?.Info($"\nFinished process {_proc.Id} with exit code {_proc.ExitCode}, and elapsed time {_stopWatch.Elapsed}.");
            }

            return(_proc.ExitCode);
        }
Пример #2
0
        private void AddQueueTriggerMethodsInAssembly(Assembly assembly, Dictionary <string, MethodInfo> queueMethods)
        {
            try
            {
                var assemblyQueueMethods = assembly
                                           .GetTypes()
                                           .Where(t => t.IsPublic)
                                           .SelectMany(t => t.GetMethods())
                                           .Where(m => m.GetQueueTriggerParameter() != null && m.IsPublic)
                                           .ToArray();

                foreach (var method in assemblyQueueMethods)
                {
                    var queueTriggerParam = method.GetQueueTriggerParameter();

                    if (queueTriggerParam != null)
                    {
                        var queueAttribute = queueTriggerParam.GetQueueTriggerAttribute();

                        if (string.IsNullOrEmpty(queueAttribute.QueueName))
                        {
                            throw new InvalidOperationException($"QueueTriggerAttribute must have a QueueName, Method: {method.Name}, Queue Trigger Parameter: {queueTriggerParam.Name}, Assembly: {assembly.GetName().Name}");
                        }

                        var queueName = queueAttribute.QueueName.ToLower();

                        if (queueMethods.ContainsKey(queueName))
                        {
                            throw new InvalidOperationException($"Cannot have multiple methods triggered by the same queue: {queueAttribute.QueueName}");
                        }

                        queueMethods.Add(queueName, method);

                        _traceWriter.Info($"Found queue trigger method {method.Name} for queue {queueName} in assembly {assembly.GetName().Name}");
                    }
                }
            }
            catch (ReflectionTypeLoadException ex)
            {
                // Don't treat this as a failure - log error and continue
                _traceWriter.Verbose($"Failed to load types for assembly {assembly.GetName().Name}:");
                foreach (var lEx in ex.LoaderExceptions)
                {
                    _traceWriter.Verbose(lEx.ToString());
                }
            }
        }
Пример #3
0
        private async Task <bool> ProcessQueueNextBatchAsync(string queueName, MethodInfo triggerMethod)
        {
            var queueClient = GetQueueClient();
            var queue       = queueClient.GetQueueReference(queueName);

            if (!queue.Exists())
            {
                // may not exist if no messages queued yet
                _traceWriter.Verbose($"Queue '{queueName}' does not exist.");
                return(false);
            }

            var visibilityTimeout = new TimeSpan(0, 0, _messageVisiblityTimeoutSeconds);

            var nextBatch = await queue.GetMessagesAsync(_queuePollBatchSize, visibilityTimeout, null, null);

            if (nextBatch == null || !nextBatch.Any())
            {
                return(false);
            }

            foreach (var message in nextBatch)
            {
                _traceWriter.Info($"Processing new message from '{queueName}'");

                try
                {
                    await ProcessMessageAsync(message, triggerMethod);
                }
                catch (Exception ex)
                {
                    _traceWriter.Error($"Failed to process message from queue {queueName}", ex);
                }

                try
                {
                    await queue.DeleteMessageAsync(message);
                }
                catch (Exception ex)
                {
                    _traceWriter.Error($"Failed to delete message from queue {queueName}", ex);
                }
            }

            return(true);
        }
Пример #4
0
        private static bool CheckSupportOfCustomServerCertificateValidation(ITraceWriter trace)
        {
            using (var handler = new HttpClientHandler())
            {
                handler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => { return(true); };

                using (var client = new HttpClient(handler))
                {
                    try
                    {
                        client.GetAsync(_testUri).GetAwaiter().GetResult();
                    }
                    catch (Exception e)
                    {
                        trace.Verbose($"SSL diagnostic data collection is disabled, due to issue:\n{e.Message}");
                        return(false);
                    }
                    return(true);
                }
            }
        }
Пример #5
0
        public static string Which(string command, bool require = false, ITraceWriter trace = null)
        {
            ArgUtil.NotNullOrEmpty(command, nameof(command));
            trace?.Info($"Which: '{command}'");
            string path = Environment.GetEnvironmentVariable(PathUtil.PathVariable);

            if (string.IsNullOrEmpty(path))
            {
                trace?.Info("PATH environment variable not defined.");
                path = path ?? string.Empty;
            }

            string[] pathSegments = path.Split(new Char[] { Path.PathSeparator }, StringSplitOptions.RemoveEmptyEntries);
            for (int i = 0; i < pathSegments.Length; i++)
            {
                pathSegments[i] = Environment.ExpandEnvironmentVariables(pathSegments[i]);
            }

            foreach (string pathSegment in pathSegments)
            {
                if (!string.IsNullOrEmpty(pathSegment) && Directory.Exists(pathSegment))
                {
                    string[] matches = null;

                    if (PlatformUtil.RunningOnWindows)
                    {
                        string pathExt = Environment.GetEnvironmentVariable("PATHEXT");
                        if (string.IsNullOrEmpty(pathExt))
                        {
                            // XP's system default value for PATHEXT system variable
                            pathExt = ".com;.exe;.bat;.cmd;.vbs;.vbe;.js;.jse;.wsf;.wsh";
                        }

                        string[] pathExtSegments = pathExt.Split(new char[] { Path.PathSeparator }, StringSplitOptions.RemoveEmptyEntries);

                        // if command already has an extension.
                        if (pathExtSegments.Any(ext => command.EndsWith(ext, StringComparison.OrdinalIgnoreCase)))
                        {
                            try
                            {
                                matches = Directory.GetFiles(pathSegment, command);
                            }
                            catch (UnauthorizedAccessException ex)
                            {
                                trace?.Info("Ignore UnauthorizedAccess exception during Which.");
                                trace?.Verbose(ex.ToString());
                            }

                            if (matches != null && matches.Length > 0)
                            {
                                trace?.Info($"Location: '{matches.First()}'");
                                return(matches.First());
                            }
                        }
                        else
                        {
                            string searchPattern = StringUtil.Format($"{command}.*");
                            try
                            {
                                matches = Directory.GetFiles(pathSegment, searchPattern);
                            }
                            catch (UnauthorizedAccessException ex)
                            {
                                trace?.Info("Ignore UnauthorizedAccess exception during Which.");
                                trace?.Verbose(ex.ToString());
                            }

                            if (matches != null && matches.Length > 0)
                            {
                                // add extension.
                                for (int i = 0; i < pathExtSegments.Length; i++)
                                {
                                    string fullPath = Path.Combine(pathSegment, $"{command}{pathExtSegments[i]}");
                                    if (matches.Any(p => p.Equals(fullPath, StringComparison.OrdinalIgnoreCase)))
                                    {
                                        trace?.Info($"Location: '{fullPath}'");
                                        return(fullPath);
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        try
                        {
                            matches = Directory.GetFiles(pathSegment, command);
                        }
                        catch (UnauthorizedAccessException ex)
                        {
                            trace?.Info("Ignore UnauthorizedAccess exception during Which.");
                            trace?.Verbose(ex.ToString());
                        }

                        if (matches != null && matches.Length > 0)
                        {
                            trace?.Info("Location: '{matches.First()}'");
                            return(matches.First());
                        }
                    }
                }
            }

            trace?.Info("Not found.");
            if (require)
            {
                throw new FileNotFoundException(
                          message: StringUtil.Loc("FileNotFound", command),
                          fileName: command);
            }

            return(null);
        }