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); }
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()); } } }
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); }
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); } } }
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); }