手把手教你成为Microsoft Store 个人开发者9:MSIX实现服务和自动启动(WinAPI/MFC)
手把手教你成为Microsoft Store 个人开发者9:MSIX实现服务和自动启动(WinAPI/MFC)
我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。
这些代码大部分以Linux为目标但部分代码是纯C++的,可以在任何平台上使用。
源码指引:github源码指引_初级代码游戏的博客-CSDN博客
C#是我多年以来的业余爱好,新搞的东西能用C#的就用C#了。
太长不看版:算了,劝退吧,微软没打算让你这么干。要么你就用UWP/WinUI之类的新技术吧。
我尝试把老式C++和MFC应用改成服务和自启动。
服务是服务,自启动是自启动,服务当然是开机自启动的,而且是在用户登录之前,但是服务不能和桌面交互,自启动是用户登录之后自动启动的,这两个完全不一样。
C++编写的服务打包入MSIX并设置为服务是没有问题的,安装之后就自动启动了,运行也正常。
但是自启动应用就比较麻烦,不能传递命令行参数(网上也有人反映这个问题,但是可以通过使用专门应用程序来规避),运行起来后行为和手工启动不一样,似乎受到了某些限制。
因此,将旧程序迁移到MSIX应该不是很有价值的事。不过,为了避免重复踩坑,我把相关点记录在下面。由于上面的原因,我没有尝试提交到商店,或许提交的时候又会出些别的乱子。
目录

1 引入多个项目
可以引入多个项目,但是只有一个可以作为入口点。

可以选择多个:

设置入口点:
项目右键菜单“设置为入口点”。
2 多个项目如何引用
每个项目的输出文件都会放置在软件包里,但是放置的方式是每个项目一个目录的,因此引用项目输出的时候要加上项目名称子目录,如“project1\app1.exe”。
坑:如果项目名称经过了修改,依赖项显示的名称未必是工作区里显示的名称,这里要以依赖项里显示的为准。
如果比较困惑,可以先打包出来,然后查看打包结果。之前的文章应该已经介绍过,MSIX打包的格式其实是zip,只要把文件后缀名改成zip就可以查看,如果是.msixbundle,解开之后里面的.msix还是zip格式,.msix改为zip解开后就能看到应用安装后的目录结构了。

3 修改清单文件
修改清单文件Package.appxmanifest,以“查看代码” 的方式。
3.1 先添加要使用的xml名字空间:

desktop6是用来添加服务的,uap5是用来支持自动启动的。代码:
xmlns:desktop6="http://schemas.microsoft.com/appx/manifest/desktop/windows10/6"
xmlns:uap5="http://schemas.microsoft.com/appx/manifest/uap/windows10/5"
IgnorableNamespaces="uap rescap desktop6 uap5"> -----修改
前两句是添加,第三句是修改。
3.2 然后添加服务和自启动,这两个是分开的,没有关系:
位置是在Application下面,整个工程只有一个Application,在里面添加两个扩展。
3.3 服务的代码
<desktop6:Extension Category="windows.service" EntryPoint="$targetentrypoint$" Executable="EnergySaverService\EnergySaverService.exe">
<desktop6:Service Name="EnergySaver" StartupType="auto" StartAccount="localSystem">
</desktop6:Service>
</desktop6:Extension>
注意服务的程序Executable是带有项目名称的。
服务除了这个还需要添加权限,在清单文件最后添加:

多出来的两行是添加的:
<rescap:Capability Name="packagedServices" />
<rescap:Capability Name="localSystemServices" />
有这两行安装的时候就会要求用户授权修改系统,不然服务是无法安装运行的。
3.4 自启动的代码
<uap5:Extension Category="windows.startupTask" EntryPoint="$targetentrypoint$" Executable="EnergySaver\EnergySaver.exe">
<uap5:StartupTask DisplayName="EnergySaver" Enabled="true" TaskId="EnergySaver"/>
</uap5:Extension>
注意,Enabled其实是忽略的,要启用有两种方式:让用户手动从任务管理器的“启动”去启用,或者在代码里面向用户发出请求(这意味着用户需要手动运行程序一次,而且,用WinAPI怎么调用?复杂了,资料难找)。
安装完毕后打开任务管理器,查看一下服务:

服务已经在运行(显示为“已暂停”是服务自己设置的服务状态,大部分时间都是暂停状态)。
再看看启动:

状态是“已禁用”,可以点右键“启用”,然后注销用户重新登录就能在“进程”那里看到程序已经运行。
虽然我实测C++控制台程序和MFC对话框程序(不启动对话框,自启动限制为最小化方式,打开对话框会被强制退出)运行都有同样的奇怪问题,至少自启动是成功了嘛。
我尝试了使用uap10:parameters提供命令行参数(以便和手动启动共享同一个程序),然而失败了,因为搜索到其他人一样失败了,所以或许根本没人这样用吧。
(这里是文档结束)
更多推荐



所有评论(0)