/// <summary> /// Attempts to start a new instance of the app with optional program arguments /// </summary> /// <remarks> /// This method is only functional on the published builds /// and not on debugging runs. /// </remarks> /// <param name="args">The program arguments to pass to the new instance.</param> public static void StartAppWithArgs(string args = "") { var path = Process.GetCurrentProcess().MainModule?.FileName; if (string.IsNullOrEmpty(path)) { throw new InvalidOperationException($"Invalid path: '{path}'"); } var startInfo = ProcessStartInfoFactory.Make(path, args); using var p = Process.Start(startInfo); }
public async Task <(string response, int exitCode)> SendCommandAsync(string arguments, bool openConsole, CancellationToken cancel, Action <StreamWriter>?standardInputWriter = null) { ProcessStartInfo startInfo = ProcessStartInfoFactory.Make(ProcessPath, arguments, openConsole); (string rawResponse, int exitCode) = await SendCommandAsync(startInfo, cancel, standardInputWriter).ConfigureAwait(false); string response; if (!openConsole) { response = rawResponse; } else { response = exitCode == 0 ? "{\"success\":\"true\"}" : $"{{\"success\":\"false\",\"error\":\"Process terminated with exit code: {exitCode}.\"}}"; } return(response, exitCode); }
public static void Invoke(Exception exceptionToReport) { try { var serializedException = exceptionToReport.ToSerializableException(); var base64ExceptionString = SerializableException.ToBase64String(serializedException); var args = $"crashreport -exception=\"{base64ExceptionString}\""; var path = Process.GetCurrentProcess().MainModule?.FileName; if (string.IsNullOrEmpty(path)) { throw new InvalidOperationException($"Invalid path: '{path}'"); } ProcessStartInfo startInfo = ProcessStartInfoFactory.Make(path, args); using Process? p = Process.Start(startInfo); } catch (Exception ex) { Logger.LogWarning($"There was a problem while invoking crash report: '{ex}'."); } }
public void TryInvokeCrashReport() { try { if (Attempts >= MaxRecursiveCalls) { throw new InvalidOperationException($"The crash report has been called {MaxRecursiveCalls} times. Will not continue to avoid recursion errors."); } if (string.IsNullOrEmpty(Base64ExceptionString)) { throw new InvalidOperationException($"The crash report exception message is empty."); } var args = $"crashreport -attempt=\"{Attempts + 1}\" -exception=\"{Base64ExceptionString}\""; ProcessStartInfo startInfo = ProcessStartInfoFactory.Make(Process.GetCurrentProcess().MainModule.FileName, args); using Process p = Process.Start(startInfo); } catch (Exception ex) { Logger.LogWarning($"There was a problem while invoking crash report:{ex.ToUserFriendlyString()}."); } }
/// <summary> /// This method can be called only once. /// </summary> public async Task StartAsync(CancellationToken cancel) { int ptcv = PrintToConsole ? 1 : 0; string processPath = MicroserviceHelpers.GetBinaryPath("bitcoind"); string networkArgument = NetworkTranslator.GetCommandLineArguments(Network); string args = $"{networkArgument} -datadir=\"{DataDir}\" -printtoconsole={ptcv}"; // Start bitcoind process. Process = new ProcessAsync(ProcessStartInfoFactory.Make(processPath, args)); Process.Start(); // Store PID in PID file. await PidFile.WriteFileAsync(Process.Id).ConfigureAwait(false); CachedPid = Process.Id; try { var exceptionTracker = new LastExceptionTracker(); // Try to connect to bitcoin daemon RPC until we succeed. while (true) { try { TimeSpan timeSpan = await RpcClient.UptimeAsync(cancel).ConfigureAwait(false); Logger.LogInfo("RPC connection is successfully established."); Logger.LogDebug($"RPC uptime is: {timeSpan}."); // Bitcoin daemon is started. We are done. break; } catch (Exception ex) { ExceptionInfo exceptionInfo = exceptionTracker.Process(ex); // Don't log extensively. if (exceptionInfo.IsFirst) { Logger.LogInfo($"{Constants.BuiltinBitcoinNodeName} is not yet ready... Reason: {exceptionInfo.Exception.Message}"); } if (Process is { } p&& p.HasExited) { throw new BitcoindException($"Failed to start daemon, location: '{p.StartInfo.FileName} {p.StartInfo.Arguments}'", ex); } } if (cancel.IsCancellationRequested) { Logger.LogDebug("Bitcoin daemon was not started yet and user requested to cancel the operation."); await StopAsync(onlyOwned : true).ConfigureAwait(false); cancel.ThrowIfCancellationRequested(); } // Wait a moment before the next check. await Task.Delay(100, cancel).ConfigureAwait(false); } } catch (Exception) { Process?.Dispose(); throw; } }