using ITNexusAgent.Models; using System.Diagnostics; using System.Management; using System.Net.Http; namespace ITNexusAgent.Services; public class CommandExecutor(ApiService api, string hostname, string dataDir, string exePath) { private readonly ApiService _api = api; private readonly string _hostname = hostname; private readonly string _dataDir = dataDir; private readonly string _exePath = exePath; private static void RunSchtasks(string args) => Process.Start(new ProcessStartInfo("schtasks.exe", args) { CreateNoWindow = true })?.WaitForExit(); public async Task ExecuteAsync(PatchCommand cmd) { string result; try { result = cmd.Command switch { "check_updates" => await CheckUpdates(), "install_updates" => await InstallUpdates(), "reboot" => await Reboot(cmd.Id), "upgrade_win11" => await UpgradeWin11(), "update_agent" => await UpdateAgent(), "shell_exec" => await ShellExec(cmd.Params ?? ""), _ => $"Unbekannter Command: {cmd.Command}" }; } catch (Exception ex) { result = $"Fehler: {ex.Message}"; } if (cmd.Command != "reboot") { await _api.ReportCommandResultAsync(new CommandResult { CommandId = cmd.Id, Status = "done", Result = result }); } } private Task CheckUpdates() { Process.Start(new ProcessStartInfo("UsoClient.exe", "StartScan") { CreateNoWindow = true }); Thread.Sleep(5000); return Task.FromResult("Update-Scan gestartet"); } private Task InstallUpdates() { Process.Start(new ProcessStartInfo("UsoClient.exe", "StartDownload") { CreateNoWindow = true }); Thread.Sleep(3000); Process.Start(new ProcessStartInfo("UsoClient.exe", "StartInstall") { CreateNoWindow = true }); return Task.FromResult("Update-Installation gestartet"); } private async Task Reboot(int cmdId) { await _api.ReportCommandResultAsync(new CommandResult { CommandId = cmdId, Status = "done", Result = "Neustart wird in 60 Sekunden durchgeführt" }); Process.Start("shutdown.exe", "/r /t 60 /c \"IT Nexus Patch Management - Geplanter Neustart\""); return ""; } private Task UpgradeWin11() { var exePath = Path.Combine(_dataDir, "Win11Upgrade.exe"); using var client = new HttpClient(); var bytes = client.GetByteArrayAsync("https://go.microsoft.com/fwlink/?linkid=2171764").Result; if (bytes.Length < 1024 * 1024) return Task.FromResult("Download fehlgeschlagen"); File.WriteAllBytes(exePath, bytes); var fullUser = NotificationService.GetLoggedOnUser(); if (!string.IsNullOrEmpty(fullUser)) { RunSchtasks("/delete /tn \"IT Nexus Win11 Upgrade\" /f"); RunSchtasks($"/create /tn \"IT Nexus Win11 Upgrade\" /tr \"\\\"{exePath}\\\" /skipeula /auto upgrade\" /sc ONCE /st {DateTime.Now.AddSeconds(20):HH:mm} /ru \"{fullUser}\" /it /rl HIGHEST /f"); } else { Process.Start(new ProcessStartInfo(exePath, "/quietinstall /skipeula /auto upgrade") { CreateNoWindow = true }); } return Task.FromResult("running"); } private Task ShellExec(string command) { if (string.IsNullOrWhiteSpace(command)) return Task.FromResult("Kein Befehl angegeben"); try { var psi = new ProcessStartInfo("powershell.exe", $"-NonInteractive -NoProfile -ExecutionPolicy Bypass -Command \"{command.Replace("\"", "\\\"")}\"") { CreateNoWindow = true, RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false }; var p = Process.Start(psi)!; var stdout = p.StandardOutput.ReadToEnd(); var stderr = p.StandardError.ReadToEnd(); p.WaitForExit(30000); var output = stdout; if (!string.IsNullOrEmpty(stderr)) output += "\n[STDERR] " + stderr; return Task.FromResult(string.IsNullOrEmpty(output) ? "(kein Output)" : output.Trim()); } catch (Exception ex) { return Task.FromResult($"Fehler: {ex.Message}"); } } private async Task UpdateAgent() { var bytes = await _api.DownloadSetupAsync(_hostname); if (bytes.Length < 512 * 1024) return "Download fehlgeschlagen - Installer zu klein"; var setupPath = Path.Combine(_dataDir, "IT-Nexus-Agent-Setup-Update.exe"); var batchPath = Path.Combine(_dataDir, "update.cmd"); await File.WriteAllBytesAsync(setupPath, bytes); // Batch: wartet kurz, führt Installer silent aus, löscht sich selbst var batch = $""" @echo off timeout /t 5 /nobreak > nul "{setupPath}" /VERYSILENT /SUPPRESSMSGBOXES /NORESTART del "{setupPath}" > nul del "%~f0" """; await File.WriteAllTextAsync(batchPath, batch, System.Text.Encoding.ASCII); Process.Start(new ProcessStartInfo("cmd.exe", $"/c \"{batchPath}\"") { CreateNoWindow = true, WindowStyle = ProcessWindowStyle.Hidden }); return "Update-Installer gestartet"; } }