steam-deck-tools/CommonHelpers/Instance.cs

299 lines
8.5 KiB
C#
Raw Normal View History

using System.Security.Principal;
using System.Security.AccessControl;
using Microsoft.Win32;
using System.Diagnostics;
2022-12-12 20:03:15 +01:00
using System.Reflection;
namespace CommonHelpers
{
public static class Instance
{
public static LibreHardwareMonitor.Hardware.Computer HardwareComputer = new LibreHardwareMonitor.Hardware.Computer
{
IsCpuEnabled = true,
IsGpuEnabled = true,
2022-11-15 19:18:44 +01:00
IsMemoryEnabled = true,
IsStorageEnabled = true,
IsBatteryEnabled = true
};
private static Mutex? runOnceMutex;
private static Mutex? globalLockMutex;
private static bool useKernelDrivers;
private const String GLOBAL_MUTEX_NAME = "Global\\SteamDeckToolsCommonHelpers";
private const int GLOBAL_DEFAULT_TIMEOUT = 10000;
public static bool WantsRunOnStartup
{
get { return Environment.GetCommandLineArgs().Contains("-run-on-startup"); }
}
public static bool Uninstall
{
get { return Environment.GetCommandLineArgs().Contains("-uninstall"); }
}
public static bool IsDEBUG
{
get
{
#if DEBUG
return true;
#else
return false;
#endif
}
}
2022-12-15 21:46:33 +01:00
public static bool IsProductionBuild
{
get
{
#if PRODUCTION_BUILD
return true;
#else
return false;
#endif
}
}
public static void OnUninstall(Action action)
{
if (Uninstall)
{
action();
Environment.Exit(0);
}
}
public static bool UseKernelDrivers
{
get { return useKernelDrivers; }
set
{
if (useKernelDrivers == value)
return;
useKernelDrivers = value;
if (value)
Vlv0100.Open();
else
Vlv0100.Close();
// CPU requires reading RyzenSMU
HardwareComputer.IsCpuEnabled = value;
HardwareComputer.Reset();
}
}
public static Mutex? WaitGlobalMutex(int timeoutMs)
{
if (globalLockMutex == null)
globalLockMutex = TryCreateOrOpenExistingMutex(GLOBAL_MUTEX_NAME);
try
{
if (globalLockMutex.WaitOne(timeoutMs))
return globalLockMutex;
return null;
}
catch (AbandonedMutexException)
{
return globalLockMutex;
}
}
public static T WithGlobalMutex<T>(int timeoutMs, Func<T> func)
{
var mutex = WaitGlobalMutex(timeoutMs);
if (mutex is null)
return default(T);
try
{
return func();
}
finally
{
mutex.ReleaseMutex();
}
}
public static void Open(String title, bool useKernelDrivers, String? runOnce = null, int runOnceTimeout = 100)
{
if (runOnce is not null)
{
RunOnce(title, runOnce, runOnceTimeout);
}
var mutex = WaitGlobalMutex(GLOBAL_DEFAULT_TIMEOUT);
if (mutex is null)
{
Fatal(title, "Failed to acquire global mutex.");
return;
}
try
{
UseKernelDrivers = useKernelDrivers;
if (Vlv0100.IsOpen && !Vlv0100.IsSupported)
{
String message = "";
message += "Current device is not supported.\n";
message += "FirmwareVersion: " + Vlv0100.FirmwareVersion.ToString("X") + "\n";
message += "BoardID: " + Vlv0100.BoardID.ToString("X") + "\n";
message += "PDCS: " + Vlv0100.PDCS.ToString("X") + "\n";
Fatal(title, message);
}
HardwareComputer.Open();
}
finally
{
mutex.ReleaseMutex();
}
}
public static void RunOnce(String? title, String mutexName, int runOnceTimeout = 1000)
{
runOnceMutex = TryCreateOrOpenExistingMutex(mutexName);
try
{
if (!runOnceMutex.WaitOne(runOnceTimeout))
{
2022-12-14 11:48:02 +01:00
Fatal(title, "Run many times", false);
}
}
catch (AbandonedMutexException)
{
// it is still OK
}
}
2022-12-14 11:34:11 +01:00
public static void WithSentry(Action action, string? dsn = null)
2022-12-12 15:08:00 +01:00
{
2022-12-16 22:32:59 +01:00
if (File.Exists("DisableCheckForUpdates.txt"))
{
action();
return;
}
2022-12-14 11:34:11 +01:00
// Overwrite DSN
if (dsn != null)
{
Log.SENTRY_DSN = dsn;
}
2022-12-12 15:08:00 +01:00
using (Sentry.SentrySdk.Init(Log.SentryOptions))
{
action();
}
}
2022-12-12 20:03:15 +01:00
public static String ApplicationName
{
get { return Assembly.GetEntryAssembly()?.GetName().Name ?? "unknown"; }
}
2022-12-17 21:37:34 +01:00
public static String ID
{
get
{
2022-12-18 23:22:27 +01:00
#if PRODUCTION_BUILD
return "";
#else
try
{
2022-12-12 20:03:15 +01:00
using (var registryKey = Registry.CurrentUser.CreateSubKey(@"Software\SteamDeckTools", true))
{
var machineID = registryKey?.GetValue("MachineID") as string;
2022-12-12 15:08:00 +01:00
if (machineID is null)
{
registryKey?.SetValue("MachineID", Guid.NewGuid().ToString());
machineID = registryKey?.GetValue("MachineID") as string;
}
2022-12-12 15:08:00 +01:00
return machineID ?? "undefined";
}
}
catch (Exception)
{
return "exception";
}
2022-12-18 23:22:27 +01:00
#endif
}
}
2022-12-16 10:05:35 +01:00
public static String ProductVersion
{
2022-12-16 10:05:35 +01:00
get => Application.ProductVersion;
}
2022-12-16 10:05:35 +01:00
public static String ProductVersionWithSha
{
2022-12-16 10:05:35 +01:00
get
{
var releaseVersion = typeof(Instance).Assembly.GetCustomAttributes<AssemblyInformationalVersionAttribute>().FirstOrDefault();
return releaseVersion?.InformationalVersion ?? ProductVersion;
}
}
2022-12-11 13:31:30 +01:00
private static System.Timers.Timer? updateTimer;
public static void RunUpdater(string Title, bool user = false, int recheckIntervalHours = 24)
{
2022-12-11 13:31:30 +01:00
// Schedule updater in 24h
if (updateTimer == null && !user && recheckIntervalHours > 0)
{
updateTimer = new System.Timers.Timer
{
Interval = recheckIntervalHours * 60 * 60 * 1000 // 24h
};
updateTimer.Elapsed += delegate { RunUpdater(Title, false); };
updateTimer.Start();
}
try
{
Process.Start(new ProcessStartInfo()
{
FileName = "Updater.exe",
2022-12-14 11:34:11 +01:00
ArgumentList = {
user ? "-user" : "-first",
"-app", ApplicationName,
"-version", ProductVersion
},
UseShellExecute = false
});
}
catch { }
}
2022-12-14 11:48:02 +01:00
public static void Fatal(String? title, String message, bool capture = true)
{
2022-12-14 11:48:02 +01:00
if (capture)
Log.TraceError("FATAL: {0}", message);
if (title is not null)
MessageBox.Show(message, title, MessageBoxButtons.OK, MessageBoxIcon.Error);
Environment.Exit(1);
}
private static Mutex TryCreateOrOpenExistingMutex(string name)
{
MutexSecurity mutexSecurity = new();
SecurityIdentifier identity = new(WellKnownSidType.WorldSid, null);
mutexSecurity.AddAccessRule(new MutexAccessRule(identity, MutexRights.Synchronize | MutexRights.Modify, AccessControlType.Allow));
var mutex = new Mutex(false, name, out _);
mutex.SetAccessControl(mutexSecurity);
return mutex;
}
}
}