using System.IO; using System.Runtime.InteropServices; using System.Text; namespace UtopiaCanteenSystem.Services.Logging; /// /// Resolves the logged-on Windows user's profile paths when the app runs as a service (SYSTEM). /// public static class InteractiveUserPath { public static string? TryGetLocalAppDataPath() { var profile = TryGetProfileDirectory(); if (string.IsNullOrWhiteSpace(profile)) return null; var localAppData = Path.Combine(profile, "AppData", "Local"); return Directory.Exists(localAppData) ? localAppData : null; } private static string? TryGetProfileDirectory() { var sessionId = WTSGetActiveConsoleSessionId(); if (sessionId == 0xFFFFFFFF) return null; if (!WTSQueryUserToken(sessionId, out var userToken) || userToken == IntPtr.Zero) return null; try { var sb = new StringBuilder(512); var size = sb.Capacity; if (!GetUserProfileDirectory(userToken, sb, ref size, out _)) return null; var path = sb.ToString(); return string.IsNullOrWhiteSpace(path) ? null : path; } finally { CloseHandle(userToken); } } [DllImport("kernel32.dll")] private static extern uint WTSGetActiveConsoleSessionId(); [DllImport("wtsapi32.dll", SetLastError = true)] private static extern bool WTSQueryUserToken(uint sessionId, out IntPtr phToken); [DllImport("userenv.dll", SetLastError = true, CharSet = CharSet.Unicode)] private static extern bool GetUserProfileDirectory(IntPtr hToken, StringBuilder lpProfileDir, ref int lpcchSize, out int lpDwFlags); [DllImport("kernel32.dll", SetLastError = true)] private static extern bool CloseHandle(IntPtr hObject); }