通过Windows注册表+任务计划程序实现开机快速启动WPF应用
最近同事正在做一款需要开机完立刻启动的WPF应用,始终没办法开机完立刻启动应用,而是在开完机后会有5s左右的时间才启动应用,因而询问我有没有思路可以提供。下面是我们问题定位与解决过程。
由于该应用需要使用系统管理员运行,使用注册表自启动没办法添加系统管理员运行,所以同事把该应用的启动放在了任务计划程序启动。使用了在Winlogon事件发生时启动(如果开始任务的时机选“登录时”,有可能系统还没完全启动,造成系统崩溃;如果选“启动时”,开始时机相对慢了)。
当前方式,重启后会出现应用在系统启动后,部分控件慢慢的加载出来;如果直接手动启动应用则界面控件瞬间加载出来。
1)一开始我怀疑是应用在系统的重启后第一次冷启动渲染资源比较慢的原因,所以把任务计划程序的自启动关闭,重启后手动启动应用,界面控件依然很快渲染出来了。
2)使用任务计划程序自启动Edge,Edge启动虽然不是很快,但是比我们的应用快挺多的。所以考虑是当前应用渲染比较慢的问题(应用该应用的启动有WPF动画)。
3)禁用硬件加速,使用软解码渲染。发现渲染效率更加慢了(因为是8K屏,如果使用了WPF动画不启动硬件加速渲染效率比较低)。
RenderOptions.ProcessRenderMode = RenderMode.SoftwareOnly;
上面的方式都没办法解决该问题,后来跟同事了解到原先不需要管理员权限启动时,通过注册表启动是很快就渲染出来的。然后我就想到一个办法:通过注册表启动1次,再通过任务计划程序启动第二次,然后再任务计划程序启动时,把注册表启动的进程杀死。这样子是不是既可以快速的渲染,也可以有管理员权限了?
在注册表的 计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon 的Userinit,把启动路径放进去,在应用内部代码判断如果当前进程有管理员权限,则把相同名字的其它进程Kill掉。
重启后,应用在账户登陆完的瞬间即立刻启动渲染完毕,并且中间不会出现有一个进程被Kill掉的闪屏问题(由于第2次启动已经是热启动,启动时间很短,肉眼感知不到闪屏)。
最后,也尝试过把启动应用加到 计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon 的Shell和ShellAppRuntime等更早的启动时机,发现办法启动应用。所以需要放在Userinit节点里面。