2023-01-15 10:29:47 +00:00
|
|
|
|
using LANCommander.SDK.Enums;
|
2023-11-10 01:40:38 +00:00
|
|
|
|
using LANCommander.SDK.Models;
|
|
|
|
|
using Microsoft.Extensions.Logging;
|
2023-01-08 18:09:57 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
2023-01-15 07:10:36 +00:00
|
|
|
|
using System.Diagnostics;
|
2023-01-08 18:09:57 +00:00
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Linq;
|
2023-01-23 04:45:47 +00:00
|
|
|
|
using System.Runtime.InteropServices;
|
2023-01-08 18:09:57 +00:00
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
2023-11-10 01:40:38 +00:00
|
|
|
|
namespace LANCommander.SDK
|
2023-01-08 18:09:57 +00:00
|
|
|
|
{
|
2023-11-10 05:45:37 +00:00
|
|
|
|
public static class PowerShellRuntime
|
2023-01-08 18:09:57 +00:00
|
|
|
|
{
|
2023-11-10 01:40:38 +00:00
|
|
|
|
public static readonly ILogger Logger;
|
2023-08-21 23:44:20 +00:00
|
|
|
|
|
2023-01-23 04:45:47 +00:00
|
|
|
|
[DllImport("kernel32.dll", SetLastError = true)]
|
|
|
|
|
static extern bool Wow64DisableWow64FsRedirection(ref IntPtr ptr);
|
2023-01-16 02:45:37 +00:00
|
|
|
|
|
2023-01-23 04:45:47 +00:00
|
|
|
|
[DllImport("kernel32.dll", SetLastError = true)]
|
|
|
|
|
static extern bool Wow64RevertWow64FsRedirection(ref IntPtr ptr);
|
2023-01-16 02:45:37 +00:00
|
|
|
|
|
2023-11-10 05:45:37 +00:00
|
|
|
|
public static void RunCommand(string command, bool asAdmin = false)
|
2023-03-30 01:49:31 +00:00
|
|
|
|
{
|
2023-11-10 01:40:38 +00:00
|
|
|
|
Logger.LogTrace($"Executing command `{command}` | Admin: {asAdmin}");
|
2023-08-21 23:44:20 +00:00
|
|
|
|
|
2023-03-30 01:49:31 +00:00
|
|
|
|
var tempScript = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".ps1");
|
|
|
|
|
|
2023-11-10 01:40:38 +00:00
|
|
|
|
Logger.LogTrace($"Creating temp script at path {tempScript}");
|
2023-08-21 23:44:20 +00:00
|
|
|
|
|
2023-03-30 01:49:31 +00:00
|
|
|
|
File.WriteAllText(tempScript, command);
|
|
|
|
|
|
|
|
|
|
RunScript(tempScript, asAdmin);
|
|
|
|
|
|
|
|
|
|
File.Delete(tempScript);
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-10 05:45:37 +00:00
|
|
|
|
public static int RunScript(string path, bool asAdmin = false, string arguments = null, string workingDirectory = null)
|
2023-01-23 04:45:47 +00:00
|
|
|
|
{
|
2023-11-10 01:40:38 +00:00
|
|
|
|
Logger.LogTrace($"Executing script at path {path} | Admin: {asAdmin} | Arguments: {arguments}");
|
2023-08-21 23:44:20 +00:00
|
|
|
|
|
2023-01-23 04:45:47 +00:00
|
|
|
|
var wow64Value = IntPtr.Zero;
|
2023-01-16 17:30:53 +00:00
|
|
|
|
|
2023-08-21 23:44:20 +00:00
|
|
|
|
// Disable Wow64 redirection so we can hit areas of the registry absolutely
|
2023-01-23 04:45:47 +00:00
|
|
|
|
Wow64DisableWow64FsRedirection(ref wow64Value);
|
2023-01-08 18:09:57 +00:00
|
|
|
|
|
2023-01-15 10:29:47 +00:00
|
|
|
|
var process = new Process();
|
2023-01-23 04:45:47 +00:00
|
|
|
|
|
2023-01-15 10:29:47 +00:00
|
|
|
|
process.StartInfo.FileName = "powershell.exe";
|
|
|
|
|
process.StartInfo.Arguments = $@"-ExecutionPolicy Unrestricted -File ""{path}""";
|
2023-03-30 01:49:31 +00:00
|
|
|
|
process.StartInfo.UseShellExecute = false;
|
2023-04-02 03:38:13 +00:00
|
|
|
|
process.StartInfo.RedirectStandardOutput = false;
|
2023-01-16 02:45:37 +00:00
|
|
|
|
|
|
|
|
|
if (arguments != null)
|
|
|
|
|
process.StartInfo.Arguments += " " + arguments;
|
|
|
|
|
|
2023-10-25 00:11:50 +00:00
|
|
|
|
if (workingDirectory != null)
|
|
|
|
|
process.StartInfo.WorkingDirectory = workingDirectory;
|
|
|
|
|
|
2023-01-23 04:45:47 +00:00
|
|
|
|
if (asAdmin)
|
2023-08-21 23:44:20 +00:00
|
|
|
|
{
|
2023-01-23 04:45:47 +00:00
|
|
|
|
process.StartInfo.Verb = "runas";
|
2023-08-21 23:44:20 +00:00
|
|
|
|
process.StartInfo.UseShellExecute = true;
|
|
|
|
|
}
|
2023-01-23 04:45:47 +00:00
|
|
|
|
|
2023-01-15 10:29:47 +00:00
|
|
|
|
process.Start();
|
|
|
|
|
process.WaitForExit();
|
2023-01-23 04:45:47 +00:00
|
|
|
|
|
|
|
|
|
Wow64RevertWow64FsRedirection(ref wow64Value);
|
2023-10-25 00:11:50 +00:00
|
|
|
|
|
|
|
|
|
return process.ExitCode;
|
2023-01-15 07:28:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-11-10 05:45:37 +00:00
|
|
|
|
public static void RunScript(Game game, ScriptType type, string arguments = null)
|
2023-08-21 23:44:20 +00:00
|
|
|
|
{
|
2023-11-10 05:45:37 +00:00
|
|
|
|
RunScript(game.InstallDirectory, type, arguments);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void RunScript(string installDirectory, ScriptType type, string arguments = null)
|
|
|
|
|
{
|
|
|
|
|
var path = GetScriptFilePath(installDirectory, type);
|
2023-08-21 23:44:20 +00:00
|
|
|
|
|
|
|
|
|
if (File.Exists(path))
|
|
|
|
|
{
|
|
|
|
|
var contents = File.ReadAllText(path);
|
|
|
|
|
|
|
|
|
|
if (contents.StartsWith("# Requires Admin"))
|
|
|
|
|
RunScript(path, true, arguments);
|
|
|
|
|
else
|
|
|
|
|
RunScript(path, false, arguments);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-10 05:45:37 +00:00
|
|
|
|
public static void RunScriptsAsAdmin(IEnumerable<string> paths, string arguments = null)
|
2023-01-20 02:02:34 +00:00
|
|
|
|
{
|
|
|
|
|
// Concatenate scripts
|
|
|
|
|
var sb = new StringBuilder();
|
|
|
|
|
|
2023-11-10 01:40:38 +00:00
|
|
|
|
Logger.LogTrace("Concatenating scripts...");
|
2023-08-21 23:44:20 +00:00
|
|
|
|
|
2023-01-20 02:02:34 +00:00
|
|
|
|
foreach (var path in paths)
|
|
|
|
|
{
|
|
|
|
|
var contents = File.ReadAllText(path);
|
|
|
|
|
|
|
|
|
|
sb.AppendLine(contents);
|
2023-08-21 23:44:20 +00:00
|
|
|
|
|
2023-11-10 01:40:38 +00:00
|
|
|
|
Logger.LogTrace($"Added {path}!");
|
2023-01-20 02:02:34 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-11-10 01:40:38 +00:00
|
|
|
|
Logger.LogTrace("Done concatenating!");
|
2023-08-21 23:44:20 +00:00
|
|
|
|
|
2023-01-20 02:02:34 +00:00
|
|
|
|
if (sb.Length > 0)
|
|
|
|
|
{
|
|
|
|
|
var scriptPath = Path.GetTempFileName();
|
|
|
|
|
|
2023-11-10 01:40:38 +00:00
|
|
|
|
Logger.LogTrace($"Creating temp script at path {scriptPath}");
|
2023-08-21 23:44:20 +00:00
|
|
|
|
|
2023-01-20 02:02:34 +00:00
|
|
|
|
File.WriteAllText(scriptPath, sb.ToString());
|
|
|
|
|
|
2023-01-23 04:45:47 +00:00
|
|
|
|
RunScript(scriptPath, true, arguments);
|
2023-01-20 02:02:34 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-10 05:45:37 +00:00
|
|
|
|
public static void RunScripts(IEnumerable<string> installDirectories, ScriptType type, string arguments = null)
|
2023-01-20 02:02:34 +00:00
|
|
|
|
{
|
|
|
|
|
List<string> scripts = new List<string>();
|
|
|
|
|
List<string> adminScripts = new List<string>();
|
|
|
|
|
|
2023-11-10 05:45:37 +00:00
|
|
|
|
foreach (var installDirectory in installDirectories)
|
2023-01-20 02:02:34 +00:00
|
|
|
|
{
|
2023-11-10 05:45:37 +00:00
|
|
|
|
var path = GetScriptFilePath(installDirectory, type);
|
2023-01-20 02:02:34 +00:00
|
|
|
|
|
|
|
|
|
if (!File.Exists(path))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
var contents = File.ReadAllText(path);
|
|
|
|
|
|
|
|
|
|
if (contents.StartsWith("# Requires Admin"))
|
|
|
|
|
adminScripts.Add(path);
|
|
|
|
|
else
|
|
|
|
|
scripts.Add(path);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RunScriptsAsAdmin(adminScripts, arguments);
|
|
|
|
|
|
|
|
|
|
foreach (var script in scripts)
|
|
|
|
|
{
|
2023-01-23 04:45:47 +00:00
|
|
|
|
RunScript(script, false, arguments);
|
2023-01-20 02:02:34 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-15 10:56:56 +00:00
|
|
|
|
public static string GetScriptFilePath(Game game, ScriptType type)
|
2023-11-10 05:45:37 +00:00
|
|
|
|
{
|
|
|
|
|
return GetScriptFilePath(game.InstallDirectory, type);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static string GetScriptFilePath(string installDirectory, ScriptType type)
|
2023-01-15 10:56:56 +00:00
|
|
|
|
{
|
|
|
|
|
Dictionary<ScriptType, string> filenames = new Dictionary<ScriptType, string>() {
|
|
|
|
|
{ ScriptType.Install, "_install.ps1" },
|
|
|
|
|
{ ScriptType.Uninstall, "_uninstall.ps1" },
|
|
|
|
|
{ ScriptType.NameChange, "_changename.ps1" },
|
|
|
|
|
{ ScriptType.KeyChange, "_changekey.ps1" }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var filename = filenames[type];
|
|
|
|
|
|
2023-11-10 05:45:37 +00:00
|
|
|
|
return Path.Combine(installDirectory, filename);
|
2023-01-15 10:56:56 +00:00
|
|
|
|
}
|
2023-01-08 18:09:57 +00:00
|
|
|
|
}
|
|
|
|
|
}
|