From 65e26e59ddcc0f35b1fd34f36617cdae22b07f2f Mon Sep 17 00:00:00 2001 From: Oliver Kieselbach Date: Sat, 7 Mar 2026 19:27:30 +0100 Subject: [PATCH] fix summary dialog start issues --- .../Core/MonitoringService.EventUpload.cs | 46 ++++++++++++++++-- .../AutopilotMonitor.Agent/buildcounter.txt | 2 +- .../App.xaml.cs | 46 ++++++++++++++++-- .../AutopilotMonitor.SummaryDialog.csproj | 1 + .../AutopilotMonitor.SummaryDialog/app.ico | Bin 0 -> 8173 bytes 5 files changed, 86 insertions(+), 9 deletions(-) create mode 100644 src/Agent/AutopilotMonitor.SummaryDialog/app.ico diff --git a/src/Agent/AutopilotMonitor.Agent.Core/Monitoring/Core/MonitoringService.EventUpload.cs b/src/Agent/AutopilotMonitor.Agent.Core/Monitoring/Core/MonitoringService.EventUpload.cs index 5b93e57f..85e78b91 100644 --- a/src/Agent/AutopilotMonitor.Agent.Core/Monitoring/Core/MonitoringService.EventUpload.cs +++ b/src/Agent/AutopilotMonitor.Agent.Core/Monitoring/Core/MonitoringService.EventUpload.cs @@ -3,6 +3,8 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; +using System.Security.AccessControl; +using System.Security.Principal; using System.Threading; using System.Threading.Tasks; using AutopilotMonitor.Agent.Core.Configuration; @@ -608,15 +610,20 @@ namespace AutopilotMonitor.Agent.Core.Monitoring.Core return; } - // Create temp folder for the dialog (survives agent self-destruct). - // Use ProgramData instead of Path.GetTempPath() because the agent runs as SYSTEM - // and SYSTEM's temp (C:\WINDOWS\SystemTemp) is not accessible to the user session. + // Create temp folder for the dialog OUTSIDE the AutopilotMonitor folder. + // The agent's self-destruct deletes ProgramData\AutopilotMonitor entirely, + // so the dialog files must live elsewhere to survive. var tempDir = Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), - "AutopilotMonitor", - "Summary-" + Guid.NewGuid().ToString("N").Substring(0, 8)); + "AutopilotMonitor-Summary"); + + // Clean up any leftover folder from a previous run, then create fresh + try { if (Directory.Exists(tempDir)) Directory.Delete(tempDir, true); } catch { } Directory.CreateDirectory(tempDir); + // Grant the interactive user delete permissions so the dialog can self-cleanup + GrantUserDeletePermission(tempDir); + // Copy dialog EXE + Newtonsoft.Json.dll + final-status.json to temp var tempDialogExe = Path.Combine(tempDir, "AutopilotMonitor.SummaryDialog.exe"); File.Copy(dialogExe, tempDialogExe); @@ -625,6 +632,10 @@ namespace AutopilotMonitor.Agent.Core.Monitoring.Core if (File.Exists(jsonDll)) File.Copy(jsonDll, Path.Combine(tempDir, "Newtonsoft.Json.dll")); + var exeConfig = dialogExe + ".config"; + if (File.Exists(exeConfig)) + File.Copy(exeConfig, tempDialogExe + ".config"); + var tempStatusFile = Path.Combine(tempDir, "final-status.json"); File.Copy(statusFile, tempStatusFile); @@ -667,6 +678,31 @@ namespace AutopilotMonitor.Agent.Core.Monitoring.Core } } + /// + /// Grants the built-in Users group full control on a directory so the user-session + /// SummaryDialog process can delete it during self-cleanup. + /// + private void GrantUserDeletePermission(string directoryPath) + { + try + { + var dirInfo = new DirectoryInfo(directoryPath); + var security = dirInfo.GetAccessControl(); + var usersIdentity = new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null); + security.AddAccessRule(new FileSystemAccessRule( + usersIdentity, + FileSystemRights.FullControl, + InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, + PropagationFlags.None, + AccessControlType.Allow)); + dirInfo.SetAccessControl(security); + } + catch (Exception ex) + { + _logger.Debug($"Could not set ACL on summary folder: {ex.Message}"); + } + } + public void Dispose() { _uploadTimer?.Dispose(); diff --git a/src/Agent/AutopilotMonitor.Agent/buildcounter.txt b/src/Agent/AutopilotMonitor.Agent/buildcounter.txt index cd307095..33a21f83 100644 --- a/src/Agent/AutopilotMonitor.Agent/buildcounter.txt +++ b/src/Agent/AutopilotMonitor.Agent/buildcounter.txt @@ -1 +1 @@ -306 +308 diff --git a/src/Agent/AutopilotMonitor.SummaryDialog/App.xaml.cs b/src/Agent/AutopilotMonitor.SummaryDialog/App.xaml.cs index 73edefa3..be2cc212 100644 --- a/src/Agent/AutopilotMonitor.SummaryDialog/App.xaml.cs +++ b/src/Agent/AutopilotMonitor.SummaryDialog/App.xaml.cs @@ -12,14 +12,42 @@ namespace AutopilotMonitor.SummaryDialog internal static string BrandingImageUrl { get; private set; } internal static bool? ForceTheme { get; private set; } // true=dark, false=light, null=auto + private static string _logFile; + + public App() + { + // Set up crash logging as early as possible to diagnose launch failures + // (e.g. when launched via CreateProcessAsUser from SYSTEM service) + try + { + var exeDir = Path.GetDirectoryName( + System.Reflection.Assembly.GetExecutingAssembly().Location) ?? "."; + _logFile = Path.Combine(exeDir, "SummaryDialog.log"); + Log("App constructor — process started"); + } + catch { } + + AppDomain.CurrentDomain.UnhandledException += (s, e) => + { + Log($"UNHANDLED EXCEPTION: {e.ExceptionObject}"); + }; + + DispatcherUnhandledException += (s, e) => + { + Log($"DISPATCHER EXCEPTION: {e.Exception}"); + }; + } + protected override void OnStartup(StartupEventArgs e) { + Log($"OnStartup — args: {string.Join(" ", e.Args)}"); base.OnStartup(e); ParseArguments(e.Args); } protected override void OnExit(ExitEventArgs e) { + Log("OnExit — shutting down"); base.OnExit(e); SelfCleanup(); } @@ -67,15 +95,16 @@ namespace AutopilotMonitor.SummaryDialog var exeDir = Path.GetDirectoryName(exePath); // Only self-cleanup if running from a known staging folder - // (agent copies the dialog to ProgramData\AutopilotMonitor\Summary-* or legacy TEMP) if (exeDir == null) return; var programData = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData); - var agentStagingRoot = Path.Combine(programData, "AutopilotMonitor"); + var summaryStaging = Path.Combine(programData, "AutopilotMonitor-Summary"); + var legacyStaging = Path.Combine(programData, "AutopilotMonitor"); var tempRoot = Path.GetTempPath().TrimEnd('\\'); - var isStagedCopy = exeDir.StartsWith(agentStagingRoot, StringComparison.OrdinalIgnoreCase) + var isStagedCopy = exeDir.StartsWith(summaryStaging, StringComparison.OrdinalIgnoreCase) + || exeDir.StartsWith(legacyStaging, StringComparison.OrdinalIgnoreCase) || exeDir.StartsWith(tempRoot, StringComparison.OrdinalIgnoreCase); if (!isStagedCopy) return; @@ -99,5 +128,16 @@ namespace AutopilotMonitor.SummaryDialog // Best-effort cleanup, ignore errors } } + + internal static void Log(string message) + { + try + { + if (_logFile != null) + File.AppendAllText(_logFile, + $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}] {message}{Environment.NewLine}"); + } + catch { } + } } } diff --git a/src/Agent/AutopilotMonitor.SummaryDialog/AutopilotMonitor.SummaryDialog.csproj b/src/Agent/AutopilotMonitor.SummaryDialog/AutopilotMonitor.SummaryDialog.csproj index f3facfc2..e592db77 100644 --- a/src/Agent/AutopilotMonitor.SummaryDialog/AutopilotMonitor.SummaryDialog.csproj +++ b/src/Agent/AutopilotMonitor.SummaryDialog/AutopilotMonitor.SummaryDialog.csproj @@ -7,6 +7,7 @@ true AutopilotMonitor.SummaryDialog AutopilotMonitor.SummaryDialog + app.ico diff --git a/src/Agent/AutopilotMonitor.SummaryDialog/app.ico b/src/Agent/AutopilotMonitor.SummaryDialog/app.ico new file mode 100644 index 0000000000000000000000000000000000000000..51f344765812821134afa0cf0edeb49c6bcf4206 GIT binary patch literal 8173 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