using System.Diagnostics; using System.Reflection; using System.Security.Cryptography; using System.Security.Principal; using System.Windows.Forms; namespace MsPrivate.Launcher; internal static class Program { private const string PayloadResource = "MsPrivate.Payload.zip"; [STAThread] private static int Main() { Application.SetHighDpiMode(HighDpiMode.PerMonitorV2); Application.EnableVisualStyles(); using var mutex = new Mutex(initiallyOwned: true, @"Local\ms-private-launcher", out var ownsMutex); if (!ownsMutex) { MessageBox.Show("ms-private is already running.", "ms-private", MessageBoxButtons.OK, MessageBoxIcon.Information); return 2; } try { if (!OperatingSystem.IsWindows() || !Environment.Is64BitOperatingSystem) throw new PlatformNotSupportedException("ms-private requires 64-bit Windows."); using var identity = WindowsIdentity.GetCurrent(); if (!new WindowsPrincipal(identity).IsInRole(WindowsBuiltInRole.Administrator)) throw new UnauthorizedAccessException("Administrator rights are required."); var bytes = ReadPayload(); var payloadHash = Convert.ToHexString(SHA256.HashData(bytes)).ToLowerInvariant(); var version = Assembly.GetExecutingAssembly().GetName().Version ?? throw new InvalidDataException("The launcher version is missing."); var productVersion = $"{version.Major}.{version.Minor}.{version.Build}"; var runtimeRoot = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "ms-private", "runtime"); var runtimeName = productVersion + "-" + payloadHash[..12]; var runtimeDirectory = Path.Combine(runtimeRoot, runtimeName); PayloadInstaller.EnsureInstalled(bytes, runtimeDirectory); RemoveOlderRuntimes(runtimeRoot, runtimeDirectory); var entryPoint = Path.Combine(runtimeDirectory, "ms-private-GUI.ps1"); var powershell = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "WindowsPowerShell", "v1.0", "powershell.exe"); if (!File.Exists(powershell)) throw new FileNotFoundException("Windows PowerShell 5.1 was not found.", powershell); var start = new ProcessStartInfo { FileName = powershell, WorkingDirectory = runtimeDirectory, UseShellExecute = false, CreateNoWindow = true }; foreach (var argument in new[] { "-NoLogo", "-NoProfile", "-ExecutionPolicy", "RemoteSigned", "-File", entryPoint }) start.ArgumentList.Add(argument); using var process = Process.Start(start) ?? throw new InvalidOperationException("Windows PowerShell could not be started."); process.WaitForExit(); if (process.ExitCode != 0) throw new InvalidOperationException($"The ms-private interface exited with code {process.ExitCode}."); return 0; } catch (Exception exception) { MessageBox.Show(exception.Message, "ms-private could not start", MessageBoxButtons.OK, MessageBoxIcon.Error); return 1; } finally { mutex.ReleaseMutex(); } } private static byte[] ReadPayload() { using var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(PayloadResource) ?? throw new InvalidDataException("The embedded ms-private payload is missing."); using var memory = new MemoryStream(); stream.CopyTo(memory); return memory.ToArray(); } private static void RemoveOlderRuntimes(string runtimeRoot, string currentDirectory) { if (!Directory.Exists(runtimeRoot) || PayloadInstaller.IsReparsePoint(runtimeRoot)) return; foreach (var directory in Directory.GetDirectories(runtimeRoot)) { if (Path.GetFullPath(directory).Equals(Path.GetFullPath(currentDirectory), StringComparison.OrdinalIgnoreCase)) continue; if (PayloadInstaller.IsReparsePoint(directory)) continue; try { PayloadInstaller.DeleteOrdinaryDirectory(directory); } catch { } } } }