See More

using BytecodeApi.Extensions; using BytecodeApi.Interop; using BytecodeApi.IO; using System.Diagnostics; using System.Net.NetworkInformation; using System.Reflection; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security.Principal; using System.Text; namespace BytecodeApi; ///

/// Provides methods to manage an application. /// public static class ApplicationBase { private static bool? _DebugMode; /// /// Gets the path for the executable file that started the application, not including the executable name. /// public static string Path => AppDomain.CurrentDomain.BaseDirectory; /// /// Gets the path for the executable file that started the application, including the executable name. /// [SupportedOSPlatform("windows")] public static string FileName { get { if (field == null) { StringBuilder fileName = new(260); field = Native.GetModuleFileName(0, fileName, fileName.Capacity) != 0 ? fileName.ToString() : throw Throw.Win32(); } return field; } } /// /// Gets the of the entry assembly. /// public static Version Version => field ??= Assembly.GetEntryAssembly()?.GetName().Version ?? throw Throw.Win32(); /// /// Gets a value indicating whether was the first time this property is retrieved, or if this executable is located in a directory named like "\bin\Debug", "\bin\x86\Debug", or "\bin\x64\Debug". /// public static bool DebugMode => _DebugMode ??= Debugger.IsAttached || new[] { @"\bin\Debug", @"\bin\x86\Debug", @"\bin\x64\Debug", @"\$Build" }.Any(path => Path.Replace('/', '\\').Contains($@"{path}\", StringComparison.OrdinalIgnoreCase) || Path.Replace('/', '\\').EndsWith(path, StringComparison.OrdinalIgnoreCase)); /// /// Restarts the current with elevated privileges. Returns , if the process is already elevated; , if elevation failed; if the restart was successful. /// /// A specifying the commandline for the new . /// A callback that is invoked after the new was successfully started with elevated privileges. Depending on application type, this is typically or Application.Shutdown() in a GUI app. /// /// , if the process is already elevated; /// , if elevation failed; /// , if the restart was successful. /// [SupportedOSPlatform("windows")] public static bool? RestartElevated(string? commandLine, Action? shutdownCallback) { if (Process.IsElevated) { return null; } else { try { using System.Diagnostics.Process? process = System.Diagnostics.Process.Start(new ProcessStartInfo(FileName, commandLine ?? "") { UseShellExecute = true, Verb = "runas" }); shutdownCallback?.Invoke(); return true; } catch { return false; } } } /// /// Provides information about the current process. /// public static class Process { private static int? _SessionId; private static ProcessIntegrityLevel? _IntegrityLevel; private static bool? _IsElevated; private static ElevationType? _ElevationType; /// /// Gets the ProcessID of the current . /// public static int Id { get { if (field == 0) { using System.Diagnostics.Process process = System.Diagnostics.Process.GetCurrentProcess(); field = process.Id; } return field; } } /// /// Gets the SessionID of the current . /// public static int SessionId { get { if (_SessionId == null) { using System.Diagnostics.Process process = System.Diagnostics.Process.GetCurrentProcess(); _SessionId = process.SessionId; } return _SessionId.Value; } } /// /// Gets the mandatory integrity level for the current . /// [SupportedOSPlatform("windows")] public static ProcessIntegrityLevel IntegrityLevel { get { if (_IntegrityLevel == null) { using System.Diagnostics.Process process = System.Diagnostics.Process.GetCurrentProcess(); _IntegrityLevel = process.IntegrityLevel; } return _IntegrityLevel.Value; } } /// /// Gets a value indicating whether the current is elevated or not. /// [SupportedOSPlatform("windows")] public static bool IsElevated { get { if (_IsElevated == null) { using WindowsIdentity windowsIdentity = WindowsIdentity.GetCurrent(); _IsElevated = new WindowsPrincipal(windowsIdentity).IsInRole(WindowsBuiltInRole.Administrator); } return _IsElevated.Value; } } /// /// Gets the for the current . /// [SupportedOSPlatform("windows")] public static ElevationType ElevationType { get { if (_ElevationType == null) { nint token; using (System.Diagnostics.Process process = System.Diagnostics.Process.GetCurrentProcess()) { token = process.OpenToken(8); } try { using HGlobal elevationTypePtr = new(4); if (Native.GetTokenInformation(token, 18, elevationTypePtr.Handle, 4, out int returnLength) && returnLength == 4) { _ElevationType = (ElevationType)Marshal.ReadInt32(elevationTypePtr.Handle); } else { throw Throw.Win32(); } } finally { if (token != 0) Native.CloseHandle(token); } } return _ElevationType.Value; } } /// /// Gets the amount of private memory, in bytes, allocated for the current . /// public static long Memory { get { using System.Diagnostics.Process process = System.Diagnostics.Process.GetCurrentProcess(); return process.PrivateMemorySize64; } } /// /// Gets the of the .NET Framework that the current is running with. /// public static Version FrameworkVersion => field ??= new(typeof(object).Assembly.GetCustomAttribute()?.InformationalVersion.SubstringUntil('+') ?? throw Throw.Win32()); } /// /// Provides information about the current logon session and related information. /// [SupportedOSPlatform("windows")] public static class Session { /// /// Gets the name of the current , including the domain or workstation name. /// public static string CurrentUser => field ??= WindowsIdentity.GetCurrent().Name; /// /// Gets the name of the current , not including the domain or workstation name. /// public static string CurrentUserShort => field ??= CurrentUser.SubstringFromLast('\\'); /// /// Gets the domain in which the local computer is registered, or , if the user is not member of a domain. /// public static string? DomainName => (field ??= IPGlobalProperties.GetIPGlobalProperties().DomainName).ToNullIfEmpty(); /// /// Gets a value indicating whether the current session is an RDP session. /// public static bool IsRdp => Environment.GetEnvironmentVariable("SESSIONNAME")?.StartsWith("RDP-", StringComparison.OrdinalIgnoreCase) == true; } } [SupportedOSPlatform("windows")] file static class Native { [DllImport("kernel32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CloseHandle(nint obj); [DllImport("kernel32.dll", SetLastError = true)] public static extern uint GetModuleFileName([In] nint module, [Out] StringBuilder fileName, [In][MarshalAs(UnmanagedType.U4)] int size); [DllImport("advapi32.dll", SetLastError = true)] public static extern bool GetTokenInformation(nint tokenHandle, int tokenInformationClass, nint tokenInformation, int tokenInformationLength, out int returnLength); }