mirror of
https://github.com/ayufan/steam-deck-tools.git
synced 2025-12-06 07:12:01 +01:00
218 lines
7 KiB
C#
218 lines
7 KiB
C#
using System.Diagnostics;
|
|
using System.Runtime.InteropServices;
|
|
|
|
namespace CommonHelpers
|
|
{
|
|
public static class Dependencies
|
|
{
|
|
public static string[] Hidapi = new string[]
|
|
{
|
|
"hidapi.dll"
|
|
};
|
|
|
|
public static string[] RTSSShared = new string[]
|
|
{
|
|
"RTSSSharedMemoryNET.dll"
|
|
};
|
|
|
|
private static string[] VCRuntime = new string[]
|
|
{
|
|
"vcruntime140.dll"
|
|
};
|
|
|
|
private static string[] RTSS = new string[]
|
|
{
|
|
"RTSSHooks64.dll"
|
|
};
|
|
|
|
public static string SDTURL = "https://steam-deck-tools.ayufan.dev";
|
|
public static string VCRuntimeURL = "https://aka.ms/vs/17/release/vc_redist.x64.exe";
|
|
public static string RTSSURL = "https://www.guru3d.com/files-details/rtss-rivatuner-statistics-server-download.html";
|
|
|
|
public static void ValidateHidapi(string title)
|
|
{
|
|
ValidateVCRuntime(title);
|
|
ValidateDependency(title, "HidAPI", Hidapi, false);
|
|
}
|
|
|
|
public static void ValidateRTSSSharedMemoryNET(string title)
|
|
{
|
|
ValidateVCRuntime(title);
|
|
ValidateDependency(title, "RTSSSharedMemoryNET", RTSSShared, false);
|
|
}
|
|
|
|
public static bool EnsureRTSS(string? title = null)
|
|
{
|
|
string? libraryPath = null;
|
|
|
|
try
|
|
{
|
|
libraryPath = Microsoft.Win32.Registry.GetValue(
|
|
@"HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Unwinder\RTSS",
|
|
"InstallDir",
|
|
null
|
|
) as string;
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
|
|
return EnsureDependency(title, "Rivatuner Statistics Server", RTSS, libraryPath, RTSSURL, false);
|
|
}
|
|
|
|
private static void ValidateVCRuntime(string title)
|
|
{
|
|
InstallDependency(title, "Microsoft Visual C++ Runtime", VCRuntime, null, VCRuntimeURL, true, false);
|
|
}
|
|
|
|
private static void ValidateDependency(string title, string name, string[] dllNames, bool unload = true)
|
|
{
|
|
if (TryToLoad(dllNames, null, unload))
|
|
return;
|
|
|
|
Log.TraceError("Cannot load: {0}", dllNames);
|
|
|
|
var result = ShowDialog(
|
|
title,
|
|
name,
|
|
"Failure in loading the " + string.Join(", ", dllNames) + ".\n\n" +
|
|
"This is required dependency. Application will exit.\n",
|
|
null,
|
|
TaskDialogButton.Close
|
|
);
|
|
|
|
Environment.Exit(1);
|
|
}
|
|
|
|
private static bool EnsureDependency(string? title, string name, string[] dllNames, string? libraryPath, string url, bool required = true)
|
|
{
|
|
if (TryToLoad(dllNames, libraryPath, false))
|
|
return true;
|
|
|
|
if (title == null)
|
|
return false;
|
|
|
|
Log.TraceError("Cannot load: {0}", dllNames);
|
|
|
|
var downloadButton = new TaskDialogButton("Download");
|
|
|
|
var result = ShowDialog(
|
|
title,
|
|
name,
|
|
"Failure in loading the " + string.Join(", ", dllNames) + ".\n\n" +
|
|
"The '" + name + "' is likely not installed.\n" +
|
|
"Click Download to download it.\n",
|
|
url,
|
|
downloadButton,
|
|
TaskDialogButton.Ignore
|
|
);
|
|
|
|
if (result == downloadButton)
|
|
OpenLink(url);
|
|
|
|
return false;
|
|
}
|
|
|
|
private static void InstallDependency(string title, string name, string[] dllNames, string? libraryPath, string url, bool required = true, bool unload = true)
|
|
{
|
|
if (TryToLoad(dllNames, libraryPath, unload))
|
|
return;
|
|
|
|
Log.TraceError("Cannot load: {0}", dllNames);
|
|
|
|
var downloadButton = new TaskDialogButton("Download");
|
|
var exitButton = new TaskDialogButton("Exit");
|
|
|
|
var result = ShowDialog(
|
|
title,
|
|
name,
|
|
"Failure in loading the " + string.Join(", ", dllNames) + ".\n\n" +
|
|
"The '" + name + "' is likely not installed.\n" +
|
|
"Click Download to download it.\n" +
|
|
(required ? "Once installed start application again.\n" : ""),
|
|
url,
|
|
downloadButton,
|
|
required ? exitButton : TaskDialogButton.Ignore
|
|
);
|
|
|
|
if (result == downloadButton)
|
|
{
|
|
OpenLink(url);
|
|
Environment.Exit(1);
|
|
}
|
|
else if (result == exitButton)
|
|
{
|
|
Environment.Exit(1);
|
|
}
|
|
}
|
|
|
|
private static bool TryToLoad(string[] dllNames, string? libraryPath, bool unload = true)
|
|
{
|
|
foreach (var dllName in dllNames)
|
|
{
|
|
if (!TryToLoad(dllName, libraryPath, unload))
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private static bool IsLoaded(string dllName)
|
|
{
|
|
return GetModuleHandle(dllName) != IntPtr.Zero;
|
|
}
|
|
|
|
private static bool TryToLoad(string dllName, String? libraryPath = null, bool unload = true)
|
|
{
|
|
if (IsLoaded(dllName))
|
|
return true;
|
|
|
|
var handle = LoadLibrary(dllName);
|
|
if (handle == IntPtr.Zero && libraryPath is not null)
|
|
handle = LoadLibrary(Path.Join(libraryPath, dllName));
|
|
if (unload)
|
|
FreeLibrary(handle);
|
|
return handle != IntPtr.Zero;
|
|
}
|
|
|
|
private static TaskDialogButton ShowDialog(string caption, string heading, string text, string? url, params TaskDialogButton[] buttons)
|
|
{
|
|
var page = new TaskDialogPage();
|
|
page.Caption = caption;
|
|
foreach (var button in buttons)
|
|
page.Buttons.Add(button);
|
|
page.Icon = TaskDialogIcon.ShieldWarningYellowBar;
|
|
page.Heading = heading;
|
|
page.Text = text;
|
|
if (page.Buttons.Contains(TaskDialogButton.Help) && url is not null)
|
|
{
|
|
page.Footnote = new TaskDialogFootnote("Click help to download it.");
|
|
page.Footnote.Icon = TaskDialogIcon.Information;
|
|
|
|
page.HelpRequest += delegate
|
|
{
|
|
try { OpenLink(url); }
|
|
catch { }
|
|
};
|
|
}
|
|
|
|
return TaskDialog.ShowDialog(new Form { TopMost = true }, page, TaskDialogStartupLocation.CenterScreen);
|
|
}
|
|
|
|
public static void OpenLink(string link)
|
|
{
|
|
try { Process.Start("explorer.exe", link); }
|
|
catch { }
|
|
}
|
|
|
|
[DllImport("kernel32.dll", SetLastError = true)]
|
|
private static extern IntPtr LoadLibrary(string lpFileName);
|
|
|
|
[DllImport("kernel32.dll")]
|
|
[return: MarshalAs(UnmanagedType.Bool)]
|
|
private static extern bool FreeLibrary(IntPtr module);
|
|
|
|
[DllImport("kernel32.dll")]
|
|
private static extern IntPtr GetModuleHandle(string moduleName);
|
|
}
|
|
}
|