134 lines
3.9 KiB
C#
134 lines
3.9 KiB
C#
using System.Runtime.InteropServices;
|
|
using Microsoft.UI.Dispatching;
|
|
using Microsoft.UI.Xaml;
|
|
|
|
namespace Covenant.Setup.Ui;
|
|
|
|
internal static class Program
|
|
{
|
|
[STAThread]
|
|
private static void Main(string[] args)
|
|
{
|
|
WinRT.ComWrappersSupport.InitializeComWrappers();
|
|
|
|
var mockScenarioName = ReadMockScenario(args);
|
|
Mocking.Scenario? mockScenario = null;
|
|
if (mockScenarioName is not null)
|
|
{
|
|
try
|
|
{
|
|
mockScenario = Mocking.Scenario.LoadFile(mockScenarioName);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
UiTrace.Write("mock_scenario_load_error", new { ex.Message });
|
|
NativeDialog.Show(IntPtr.Zero, $"Failed to load mock scenario: {ex.Message}", "covenant-setup", NativeDialogIcon.Error);
|
|
return;
|
|
}
|
|
}
|
|
|
|
var pipeName = ReadPipeName(args);
|
|
if (string.IsNullOrWhiteSpace(pipeName))
|
|
{
|
|
if (mockScenario is not null)
|
|
{
|
|
pipeName = $"covenant-setup-mock-{Environment.ProcessId}-{Guid.NewGuid():N}";
|
|
}
|
|
else
|
|
{
|
|
UiTrace.Write("missing_pipe_argument");
|
|
NativeDialog.Show(IntPtr.Zero, "Missing named pipe argument.", "covenant-setup", NativeDialogIcon.Error);
|
|
return;
|
|
}
|
|
}
|
|
|
|
UiTrace.Write("process_start", new { ProcessId = Environment.ProcessId, PipeName = pipeName });
|
|
|
|
Application.Start(_params =>
|
|
{
|
|
var dispatcherQueue = DispatcherQueue.GetForCurrentThread();
|
|
if (dispatcherQueue is not null)
|
|
{
|
|
SynchronizationContext.SetSynchronizationContext(
|
|
new DispatcherQueueSynchronizationContext(dispatcherQueue));
|
|
}
|
|
|
|
_ = new InstallerUiApp(pipeName, mockScenario);
|
|
});
|
|
}
|
|
|
|
internal static string? ReadPipeName(string[] args)
|
|
{
|
|
var value = ReadArgValue(args, "--pipe");
|
|
const string pipePrefix = @"\\.\pipe\";
|
|
if (value is not null && value.StartsWith(pipePrefix, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
value = value[pipePrefix.Length..];
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
internal static string? ReadMockScenario(string[] args)
|
|
{
|
|
return ReadArgValue(args, "--mock");
|
|
}
|
|
|
|
private static string? ReadArgValue(string[] args, string flag)
|
|
{
|
|
for (var i = 0; i < args.Length - 1; i++)
|
|
{
|
|
if (string.Equals(args[i], flag, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
return args[i + 1];
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public sealed partial class InstallerUiApp : Application
|
|
{
|
|
private readonly string _pipeName;
|
|
private readonly Mocking.Scenario? _mockScenario;
|
|
private Window? _window;
|
|
|
|
internal InstallerUiApp(string pipeName, Mocking.Scenario? mockScenario)
|
|
{
|
|
_pipeName = pipeName;
|
|
_mockScenario = mockScenario;
|
|
InitializeComponent();
|
|
}
|
|
|
|
protected override void OnLaunched(LaunchActivatedEventArgs args)
|
|
{
|
|
var window = new InstallerUiWindow(_pipeName);
|
|
_window = window;
|
|
window.Activate();
|
|
window.StartPipeLoop();
|
|
|
|
if (_mockScenario is not null)
|
|
{
|
|
_ = Task.Run(() => new Mocking.MockEngineClient(_pipeName, _mockScenario, new Mocking.MockEngineOptions { StrictExpectations = false }).RunAsync());
|
|
}
|
|
}
|
|
}
|
|
|
|
internal enum NativeDialogIcon : uint
|
|
{
|
|
Error = 0x00000010,
|
|
Information = 0x00000040
|
|
}
|
|
|
|
internal static class NativeDialog
|
|
{
|
|
public static void Show(IntPtr owner, string message, string title, NativeDialogIcon icon)
|
|
{
|
|
_ = MessageBoxW(owner, message, title, (uint)icon);
|
|
}
|
|
|
|
[DllImport("user32.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
|
|
private static extern int MessageBoxW(IntPtr hWnd, string text, string caption, uint type);
|
|
}
|