Squirrel 进程通过启动子进程调用你的应用来传递事件消息. 比如说第一次安装完成时, 会通过以下命令来传递事件消息:
MyApp.exe --squirrel-install x.y.z.m
使用 C# 代码实现后台定时检查更新
以下代码使用 Process 启动更新程序, 并在程序中使用定时器来定期检查更新.
需要注意的是执行安装程序时, 会先将程序解压到 %LocalAppData%\SquirrelTemp 目录中, 此时 squirrel.exe 的工作目录也在此处. 在安装结束启动新进程调用 app 传递事件消息时, 子进程的工作目录默认与父进程相同. 所以在处理--squirrel-install事件时, 为了调用 squirrel.exe 来创建快捷方式, 必须指定绝对路径, 否则会找不到可执行文件.
在程序入口点处理 squirrel 事件
以下代码在初次安装成功后创建桌面快捷方式, 在卸载时删除快捷方式.
var AppDirectory = Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..")); var SquirrelFilePath = Path.Combine(AppDirectory, "Update.exe"); var AppName = new DirectoryInfo(AppDirectory).Name; await UpdateManager.HandleSquirrelEventsAsync( async version => await UpdateManager.InvokeProcessAsync(SquirrelFilePath, $"--createShortcut {AppName}.exe", AppDirectory),//创建快捷方式 async version => await UpdateManager.InvokeProcessAsync(SquirrelFilePath, $"--removeShortcut {AppName}.exe", AppDirectory),//删除快捷方式 (version) => { MessageBox.Show($"onAppUpdate 版本:{version} 已下载完成, 请关闭应用."); return Task.CompletedTask; }, (version) => { MessageBox.Show("onAppObsoleted"); return Task.CompletedTask; }, () => { MessageBox.Show("欢迎使用本 APP !"); return Task.CompletedTask; });HandleSquirrelEventsAsync 方法
Squirrel.SquirrelAwareApp.HandleEvents 方法用于帮助处理 Squirrel 事件. 以下代码在源码的基础上调整为异步委托, 并在委托调用失败时, 将错误信息写入 Windows Application event log, 方便调试.
/// <summary> /// 处理 Squirrel 事件 /// </summary> /// <param>在应用程序初始化安装结束时调用</param> /// <param>在应用程序更新结束时调用</param> /// <param>在应用程序不是最新版本时调用</param> /// <param>在应用程序卸载结束时调用</param> /// <param>在应用程序第一次启动时调用</param> public static async Task HandleSquirrelEventsAsync( Func<Version, Task> onInitialInstall = null, Func<Version, Task> onAppUninstall = null, Func<Version, Task> onAppUpdate = null, Func<Version, Task> onAppObsoleted = null, Func<Task> onFirstRun = null, string[] arguments = null) { Func<Version, Task> defaultBlock = v => Task.CompletedTask; var args = arguments ?? Environment.GetCommandLineArgs().Skip(1).ToArray(); if (args.Length == 0) return; var lookup = new[] { new { Key = "--squirrel-install", Value = onInitialInstall ?? defaultBlock }, new { Key = "--squirrel-updated", Value = onAppUpdate ?? defaultBlock }, new { Key = "--squirrel-obsolete", Value = onAppObsoleted ?? defaultBlock }, new { Key = "--squirrel-uninstall", Value = onAppUninstall ?? defaultBlock }, }.ToDictionary(k => k.Key, v => v.Value); if (args[0] == "--squirrel-firstrun") { await onFirstRun?.Invoke(); return; } if (args.Length != 2 || !lookup.ContainsKey(args[0]) ) { return; } try { var version = new Version(args[1]); await lookup[args[0]](version); Environment.Exit(0); } catch (Exception ex) { Environment.FailFast($"Fatal Exception Occurs When Handle Squirrel Events With Arguments '{args}'", ex); } } 6. 其他更新方案