59 lines
1.8 KiB
C#
59 lines
1.8 KiB
C#
using System.IO;
|
|
using System.Runtime.InteropServices;
|
|
using System.Text;
|
|
|
|
namespace UtopiaCanteenSystem.Services.Logging;
|
|
|
|
/// <summary>
|
|
/// Resolves the logged-on Windows user's profile paths when the app runs as a service (SYSTEM).
|
|
/// </summary>
|
|
internal 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);
|
|
}
|