feat.PLONDS系统开发

This commit is contained in:
lincube
2026-07-31 11:43:50 +09:00
parent 728a8d4861
commit 557e426dde
39 changed files with 5498 additions and 568 deletions

View File

@@ -1,5 +1,7 @@
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Win32;
using LanDesktopPLONDS.Installer.Services;
namespace LanDesktopPLONDS.Installer;
@@ -9,14 +11,55 @@ public static class Program
public static void Main(string[] args)
{
InstallerStartupDiagnostics.Initialize();
// 解析命令行参数
var uninstallMode = false;
var uninstallSilent = false;
string? uninstallPath = null;
for (var i = 0; i < args.Length; i++)
{
if (args[i].Equals("--uninstall", StringComparison.OrdinalIgnoreCase))
{
uninstallMode = true;
// 下一个参数是可选的 installPath
if (i + 1 < args.Length && !args[i + 1].StartsWith("-", StringComparison.Ordinal))
{
uninstallPath = args[i + 1];
i++;
}
}
else if (args[i].Equals("--uninstall-silent", StringComparison.OrdinalIgnoreCase))
{
uninstallMode = true;
uninstallSilent = true;
// 下一个参数是可选的 installPath
if (i + 1 < args.Length && !args[i + 1].StartsWith("-", StringComparison.Ordinal))
{
uninstallPath = args[i + 1];
i++;
}
}
}
// 卸载模式
if (uninstallMode)
{
RunUninstall(uninstallPath, uninstallSilent);
return;
}
// 单实例检查
using var singleInstance = new InstallerSingleInstance();
if (!singleInstance.TryAcquire())
{
Console.Error.WriteLine("安装程序已在运行,无法启动第二个实例。");
Environment.Exit(2);
return;
}
try
{
InstallerStartupDiagnostics.Log("Preparing native dependencies.");
if (!NativeDependencyBootstrapper.TryPrepare())
{
throw new InvalidOperationException("Failed to prepare native dependencies.");
}
InstallerStartupDiagnostics.Log("Starting Avalonia desktop lifetime.");
BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
}
@@ -26,6 +69,99 @@ public static class Program
}
}
/// <summary>
/// 执行卸载流程。
/// </summary>
private static void RunUninstall(string? installPath, bool silent)
{
if (string.IsNullOrWhiteSpace(installPath))
{
Console.Error.WriteLine("卸载需要指定安装路径参数。");
Environment.Exit(1);
return;
}
try
{
// 非静默模式:显示确认窗口
if (!silent)
{
var confirmed = ShowUninstallConfirmation(installPath);
if (!confirmed)
{
Console.WriteLine("用户取消了卸载操作。");
Environment.Exit(0);
return;
}
}
var service = new UninstallService(installPath, silent);
var success = service.Execute();
Environment.Exit(success ? 0 : 1);
}
catch (UnauthorizedAccessException ex)
{
Console.Error.WriteLine($"卸载失败:{ex.Message}");
Environment.Exit(1);
}
catch (InvalidOperationException ex)
{
Console.Error.WriteLine($"卸载失败:{ex.Message}");
Environment.Exit(1);
}
catch (Exception ex)
{
Console.Error.WriteLine($"卸载过程中发生意外错误:{ex.Message}");
Environment.Exit(1);
}
}
/// <summary>
/// 显示卸载确认窗口(非静默模式)。
/// 返回 true 表示用户确认卸载。
/// </summary>
private static bool ShowUninstallConfirmation(string installPath)
{
var confirmed = false;
var resetEvent = new ManualResetEventSlim(false);
// 在新线程启动 Avalonia 卸载确认窗口
var thread = new Thread(() =>
{
try
{
var appBuilder = AppBuilder.Configure<UninstallConfirmApp>()
.UsePlatformDetect()
.With(new Win32PlatformOptions
{
RenderingMode = [Win32RenderingMode.Software],
CompositionMode = [Win32CompositionMode.RedirectionSurface]
});
var app = new UninstallConfirmApp();
app.ConfirmAction += result =>
{
confirmed = result;
resetEvent.Set();
app.ShutdownApp();
};
app.InstallPath = installPath;
appBuilder.StartWithClassicDesktopLifetime([]);
}
catch
{
resetEvent.Set();
}
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
resetEvent.Wait();
return confirmed;
}
public static AppBuilder BuildAvaloniaApp()
{
return AppBuilder.Configure<App>()
@@ -37,3 +173,64 @@ public static class Program
});
}
}
/// <summary>
/// 卸载确认窗口的临时 App 类。
/// </summary>
internal sealed class UninstallConfirmApp : Application
{
private IClassicDesktopStyleApplicationLifetime? _lifetime;
public event Action<bool>? ConfirmAction;
public string InstallPath { get; set; } = string.Empty;
public override void OnFrameworkInitializationCompleted()
{
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
_lifetime = desktop;
var window = new Views.UninstallConfirmWindow
{
DataContext = new UninstallConfirmViewModel(InstallPath, ConfirmAction!)
};
desktop.MainWindow = window;
window.Show();
}
base.OnFrameworkInitializationCompleted();
}
/// <summary>
/// 关闭应用程序。
/// </summary>
public void ShutdownApp()
{
_lifetime?.Shutdown();
}
}
/// <summary>
/// 卸载确认窗口的视图模型。
/// </summary>
internal sealed class UninstallConfirmViewModel
{
private readonly Action<bool> _confirmAction;
public UninstallConfirmViewModel(string installPath, Action<bool> confirmAction)
{
InstallPath = installPath;
_confirmAction = confirmAction;
}
public string InstallPath { get; }
public void Confirm()
{
_confirmAction(true);
}
public void Cancel()
{
_confirmAction(false);
}
}