generated from MrSphay/codex-agent-repository-kit
193 lines
7.0 KiB
C#
193 lines
7.0 KiB
C#
using System;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Text;
|
|
using System.Windows.Forms;
|
|
|
|
namespace MrTrust
|
|
{
|
|
internal static class MrTrustLauncher
|
|
{
|
|
private const string PayloadResourcePrefix = "MrTrust.Payload.";
|
|
|
|
private static readonly PayloadFile[] PayloadFiles =
|
|
{
|
|
new PayloadFile("MrTrust.ps1", "MrTrust.ps1"),
|
|
new PayloadFile("scripts.Build-MrTrustExe.ps1", Path.Combine("scripts", "Build-MrTrustExe.ps1")),
|
|
new PayloadFile("scripts.Install-MrTrust.ps1", Path.Combine("scripts", "Install-MrTrust.ps1")),
|
|
new PayloadFile("scripts.New-MrTrustCertificate.ps1", Path.Combine("scripts", "New-MrTrustCertificate.ps1")),
|
|
new PayloadFile("scripts.New-MrTrustIcon.ps1", Path.Combine("scripts", "New-MrTrustIcon.ps1")),
|
|
new PayloadFile("scripts.New-MrTrustRelease.ps1", Path.Combine("scripts", "New-MrTrustRelease.ps1")),
|
|
new PayloadFile("scripts.Sign-MrTrustProject.ps1", Path.Combine("scripts", "Sign-MrTrustProject.ps1")),
|
|
new PayloadFile("scripts.Sign-MrTrustProjectLinux.sh", Path.Combine("scripts", "Sign-MrTrustProjectLinux.sh")),
|
|
new PayloadFile("scripts.Start-MrTrustGui.ps1", Path.Combine("scripts", "Start-MrTrustGui.ps1")),
|
|
new PayloadFile("scripts.Uninstall-MrTrust.ps1", Path.Combine("scripts", "Uninstall-MrTrust.ps1")),
|
|
new PayloadFile("assets.MrTrust.ico", Path.Combine("assets", "MrTrust.ico")),
|
|
new PayloadFile("assets.certificates.MrSphay-LocalTrust-Root.cer", Path.Combine("assets", "certificates", "MrSphay-LocalTrust-Root.cer")),
|
|
new PayloadFile("assets.certificates.MrSphay-CodeSigning.cer", Path.Combine("assets", "certificates", "MrSphay-CodeSigning.cer")),
|
|
new PayloadFile("assets.certificates.thumbprints.txt", Path.Combine("assets", "certificates", "thumbprints.txt"))
|
|
};
|
|
|
|
[STAThread]
|
|
private static int Main(string[] args)
|
|
{
|
|
string baseDirectory = string.Empty;
|
|
|
|
try
|
|
{
|
|
baseDirectory = ExtractPayload();
|
|
string scriptPath = Path.Combine(baseDirectory, "MrTrust.ps1");
|
|
string commandArguments = BuildCommandArguments(args);
|
|
|
|
ProcessStartInfo startInfo = new ProcessStartInfo
|
|
{
|
|
FileName = "powershell.exe",
|
|
Arguments = "-NoProfile -ExecutionPolicy Bypass -File " + QuoteArgument(scriptPath) + " " + commandArguments,
|
|
UseShellExecute = false,
|
|
CreateNoWindow = true,
|
|
WorkingDirectory = baseDirectory
|
|
};
|
|
|
|
using (Process process = Process.Start(startInfo))
|
|
{
|
|
if (process == null)
|
|
{
|
|
throw new InvalidOperationException("PowerShell could not be started.");
|
|
}
|
|
|
|
process.WaitForExit();
|
|
return process.ExitCode;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
MessageBox.Show(
|
|
ex.Message,
|
|
"MrTrust",
|
|
MessageBoxButtons.OK,
|
|
MessageBoxIcon.Error);
|
|
return 1;
|
|
}
|
|
finally
|
|
{
|
|
TryDeleteDirectory(baseDirectory);
|
|
}
|
|
}
|
|
|
|
private static string ExtractPayload()
|
|
{
|
|
Assembly assembly = Assembly.GetExecutingAssembly();
|
|
string versionKey = GetPayloadVersionKey(assembly);
|
|
string targetDirectory = Path.Combine(
|
|
Path.GetTempPath(),
|
|
"MrTrust",
|
|
"standalone",
|
|
versionKey,
|
|
Guid.NewGuid().ToString("N"));
|
|
|
|
foreach (PayloadFile payloadFile in PayloadFiles)
|
|
{
|
|
string targetPath = Path.Combine(targetDirectory, payloadFile.RelativePath);
|
|
string targetParent = Path.GetDirectoryName(targetPath);
|
|
if (!string.IsNullOrEmpty(targetParent))
|
|
{
|
|
Directory.CreateDirectory(targetParent);
|
|
}
|
|
|
|
using (Stream stream = assembly.GetManifestResourceStream(PayloadResourcePrefix + payloadFile.ResourceName))
|
|
{
|
|
if (stream == null)
|
|
{
|
|
throw new FileNotFoundException("Embedded MrTrust payload file was not found.", payloadFile.RelativePath);
|
|
}
|
|
|
|
using (FileStream file = File.Create(targetPath))
|
|
{
|
|
stream.CopyTo(file);
|
|
}
|
|
}
|
|
}
|
|
|
|
return targetDirectory;
|
|
}
|
|
|
|
private static void TryDeleteDirectory(string directory)
|
|
{
|
|
if (string.IsNullOrEmpty(directory) || !Directory.Exists(directory))
|
|
{
|
|
return;
|
|
}
|
|
|
|
try
|
|
{
|
|
Directory.Delete(directory, true);
|
|
}
|
|
catch
|
|
{
|
|
// Best-effort cleanup only. A locked icon or antivirus scan should not mask the command result.
|
|
}
|
|
}
|
|
|
|
private static string GetPayloadVersionKey(Assembly assembly)
|
|
{
|
|
string location = Application.ExecutablePath;
|
|
if (File.Exists(location))
|
|
{
|
|
FileInfo fileInfo = new FileInfo(location);
|
|
return fileInfo.Length.ToString("x") + "-" + fileInfo.LastWriteTimeUtc.Ticks.ToString("x");
|
|
}
|
|
|
|
return assembly.GetName().Version.ToString();
|
|
}
|
|
|
|
private static string BuildCommandArguments(string[] args)
|
|
{
|
|
string[] effectiveArgs = args.Length == 0 ? new[] { "gui" } : args;
|
|
return string.Join(" ", effectiveArgs.Select(QuoteArgument).ToArray());
|
|
}
|
|
|
|
private static string QuoteArgument(string value)
|
|
{
|
|
if (string.IsNullOrEmpty(value))
|
|
{
|
|
return "\"\"";
|
|
}
|
|
|
|
if (value.IndexOfAny(new[] { ' ', '\t', '\n', '\r', '"' }) < 0)
|
|
{
|
|
return value;
|
|
}
|
|
|
|
StringBuilder builder = new StringBuilder();
|
|
builder.Append('"');
|
|
foreach (char character in value)
|
|
{
|
|
if (character == '"')
|
|
{
|
|
builder.Append('\\');
|
|
}
|
|
|
|
builder.Append(character);
|
|
}
|
|
|
|
builder.Append('"');
|
|
return builder.ToString();
|
|
}
|
|
|
|
private sealed class PayloadFile
|
|
{
|
|
public PayloadFile(string resourceName, string relativePath)
|
|
{
|
|
ResourceName = resourceName;
|
|
RelativePath = relativePath;
|
|
}
|
|
|
|
public string ResourceName { get; private set; }
|
|
|
|
public string RelativePath { get; private set; }
|
|
}
|
|
}
|
|
}
|