mirror of
https://github.com/okieselbach/AutopilotMonitor.git
synced 2026-10-24 20:53:06 +00:00
fix summary dialog start issues
This commit is contained in:
+41
-5
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Grants the built-in Users group full control on a directory so the user-session
|
||||
/// SummaryDialog process can delete it during self-cleanup.
|
||||
/// </summary>
|
||||
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();
|
||||
|
||||
@@ -1 +1 @@
|
||||
306
|
||||
308
|
||||
|
||||
@@ -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 { }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
<UseWPF>true</UseWPF>
|
||||
<AssemblyName>AutopilotMonitor.SummaryDialog</AssemblyName>
|
||||
<RootNamespace>AutopilotMonitor.SummaryDialog</RootNamespace>
|
||||
<ApplicationIcon>app.ico</ApplicationIcon>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 8.0 KiB |
Reference in New Issue
Block a user