/// Starts a cache session private async Task <int> RunUsingElevatedService(ElevationRequest elevationRequest) { Logger.Instance.Log($"Using Console mode {elevationRequest.Mode}", LogLevel.Debug); var cmd = CommandToRun.FirstOrDefault(); Rpc.Connection connection = null; try { connection = await ConnectStartElevatedService().ConfigureAwait(false); if (connection == null) // service is not running or listening. { Logger.Instance.Log("Unable to connect to the elevated service.", LogLevel.Error); return(Constants.GSUDO_ERROR_EXITCODE); } var renderer = GetRenderer(connection, elevationRequest); await connection.WriteElevationRequest(elevationRequest).ConfigureAwait(false); ConnectionKeepAliveThread.Start(connection); var exitCode = await renderer.Start().ConfigureAwait(false); return(exitCode); } finally { connection?.Dispose(); } }
public async Task <int> Execute() { //Logger.Instance.Log("Params: " + Newtonsoft.Json.JsonConvert.SerializeObject(this), LogLevel.Debug); var currentProcess = System.Diagnostics.Process.GetCurrentProcess(); bool emptyArgs = string.IsNullOrEmpty(CommandToRun.FirstOrDefault()); CommandToRun = ArgumentsHelper.AugmentCommand(CommandToRun.ToArray()); bool isWindowsApp = ProcessFactory.IsWindowsApp(CommandToRun.FirstOrDefault()); var consoleMode = GetConsoleMode(isWindowsApp); if (!RunningAsDesiredUser()) { CommandToRun = AddCopyEnvironment(CommandToRun); } var exeName = CommandToRun.FirstOrDefault(); var elevationRequest = new ElevationRequest() { FileName = exeName, Arguments = GetArguments(), StartFolder = Environment.CurrentDirectory, NewWindow = GlobalSettings.NewWindow, Wait = (!isWindowsApp && !GlobalSettings.NewWindow) || GlobalSettings.Wait, Mode = consoleMode, ConsoleProcessId = currentProcess.Id, Prompt = consoleMode != ElevationRequest.ConsoleMode.Raw || GlobalSettings.NewWindow ? GlobalSettings.Prompt : GlobalSettings.RawPrompt }; Logger.Instance.Log($"Command to run: {elevationRequest.FileName} {elevationRequest.Arguments}", LogLevel.Debug); if (elevationRequest.Mode == ElevationRequest.ConsoleMode.VT) { elevationRequest.ConsoleWidth = Console.WindowWidth; elevationRequest.ConsoleHeight = Console.WindowHeight; if (TerminalHelper.IsConEmu()) { elevationRequest.ConsoleWidth--; // weird ConEmu/Cmder fix } } if (RunningAsDesiredUser()) // already elevated or running as correct user. No service needed. { if (emptyArgs && !GlobalSettings.NewWindow) { Logger.Instance.Log("Already elevated (and no parameters specified). Exiting...", LogLevel.Error); return(Constants.GSUDO_ERROR_EXITCODE); } Logger.Instance.Log("Already elevated. Running in-process", LogLevel.Debug); // No need to escalate. Run in-process if (elevationRequest.Mode == ElevationRequest.ConsoleMode.Raw && !elevationRequest.NewWindow) { if (!string.IsNullOrEmpty(GlobalSettings.RawPrompt.Value)) { Environment.SetEnvironmentVariable("PROMPT", Environment.ExpandEnvironmentVariables(GlobalSettings.RawPrompt.Value)); } } else { if (!string.IsNullOrEmpty(GlobalSettings.Prompt.Value)) { Environment.SetEnvironmentVariable("PROMPT", Environment.ExpandEnvironmentVariables(GlobalSettings.Prompt.Value)); } } if (GlobalSettings.NewWindow) { using (Process process = ProcessFactory.StartDetached(exeName, GetArguments(), Environment.CurrentDirectory, false)) { if (elevationRequest.Wait) { process.WaitForExit(); var exitCode = process.ExitCode; Logger.Instance.Log($"Elevated process exited with code {exitCode}", exitCode == 0 ? LogLevel.Debug : LogLevel.Info); return(exitCode); } return(0); } } else { using (Process process = ProcessFactory.StartInProcessAtached(exeName, GetArguments())) { process.WaitForExit(); var exitCode = process.ExitCode; Logger.Instance.Log($"Elevated process exited with code {exitCode}", exitCode == 0 ? LogLevel.Debug : LogLevel.Info); return(exitCode); } } } else { Logger.Instance.Log($"Using Console mode {elevationRequest.Mode}", LogLevel.Debug); var callingPid = GetCallingPid(currentProcess); var callingSid = WindowsIdentity.GetCurrent().User.Value; Logger.Instance.Log($"Caller PID: {callingPid}", LogLevel.Debug); Logger.Instance.Log($"Caller SID: {callingSid}", LogLevel.Debug); var cmd = CommandToRun.FirstOrDefault(); var rpcClient = GetClient(elevationRequest); Rpc.Connection connection = null; try { try { connection = await rpcClient.Connect(elevationRequest, null, 300).ConfigureAwait(false); } catch (System.IO.IOException) { } catch (TimeoutException) { } catch (Exception ex) { Logger.Instance.Log(ex.ToString(), LogLevel.Warning); } if (connection == null) // service is not running or listening. { // Start elevated service instance if (!StartElevatedService(currentProcess, callingPid, callingSid)) { return(Constants.GSUDO_ERROR_EXITCODE); } connection = await rpcClient.Connect(elevationRequest, callingPid, 5000).ConfigureAwait(false); } if (connection == null) // service is not running or listening. { Logger.Instance.Log("Unable to connect to the elevated service.", LogLevel.Error); return(Constants.GSUDO_ERROR_EXITCODE); } await WriteElevationRequest(elevationRequest, connection).ConfigureAwait(false); ConnectionKeepAliveThread.Start(connection); var renderer = GetRenderer(connection, elevationRequest); var exitCode = await renderer.Start().ConfigureAwait(false); if (!(elevationRequest.NewWindow && !elevationRequest.Wait)) { Logger.Instance.Log($"Elevated process exited with code {exitCode}", exitCode == 0 ? LogLevel.Debug : LogLevel.Info); } return(exitCode); } finally { connection?.Dispose(); } } }