Win32程序转UWP的开机启动配置(Qt/C++)
对于希望将传统的Windows桌面应用程序转化为UWP应用,微软提供了桌面桥来方便转换。虽然提供了多种形式,但实际都是将二进制的程序包根据配置打包到一个UWP应用里。
比如:Desktop App Coverter支持将已有的安装包生成一个UWP程序,实际上是在一个完整的Windows镜像环境里模拟安装该软件,并将安装目录下的文件收集并打包。所以该技术需要安装包本身支持静默安装模式。
关于打包过程,MSDN的例子足够详细,就不详细说明了。
将Windows程序打包到UWP,目前我觉得需要注意的问题有两点:
- 禁止在当前程序运行目录写入或修改文件
- 禁止修改UWP程序相关的注册表
这两个都是很容易避免的操作,毕竟不属于常用的操作,微软也希望极力打造一个更安全的应用环境。转换后的UWP程序本质还是Win32程序,可以通过任务管理器打开所在目录。
OK,进入正题:
关于如何配置软件的自启动,Win32程序的办法是在注册表中Software\Microsoft\Windows\CurrentVersion\Run中写入相应的信息即可,在UWP中只能在打包的时候在清单文件里进行配置。
参考链接:UWP程序配置开机自启动
尽管生成的UWP程序“开机启动”信息仍然是在注册表里,但一旦通过代码修改状态,程序就会退出。所以只能通过调用UWP的接口。上面的链接里有C#的例子,设置开机启动的接口不多。
参考链接:在C++程序中调用UWP接口
以下是在Qt中使用UWP接口的部分代码,
#include <ppltasks.h>
using namespace Windows::ApplicationModel;
using namespace concurrency;
//获取自启动状态
int UwpPackage::getStartupTaskState()
{
//UWP中大量使用了异步接口
//"UwpPackageStartupTask"为清单文件里配置的StartupTask的TaskId
auto asyn_op = StartupTask::GetAsync(ref new Platform::String(TEXT("UwpPackageStartupTask")));
if (asyn_op != nullptr)
{
//使用create_task等待异步任务结束
auto startup_task = concurrency::create_task(asyn_op).get();
return (int)startup_task->State;
}
return -1;
}
//返回设置的状态
int UwpPackage::setStartupTaskState(bool enable)
{
auto asyn_op = StartupTask::GetAsync(ref new Platform::String(TEXT("UwpPackageStartupTask")));
if (asyn_op != nullptr)
{
auto startup_task = concurrency::create_task(asyn_op).get();
if (enable)
{
auto startup_state = concurrency::create_task(startup_task->RequestEnableAsync()).get();
return (int)startup_state;
}
else
{
startup_task->Disable();
return (int)StartupTaskState::Disabled;
}
}
return -1;
}
补充说明:
C++ concurrency::task实现异步编程(Windows)
代码环境:
Visual Studio 2015
Qt 5.8.0 MSVC2015 64bit
Windows 10专业版
代码简单解释一下:
Windows::ApplicationModel::StartupTask 是UWP中管理自启动任务的类
StartupTask::GetAsync 获取到指定ID的实例。
StartupTask::Disable 禁用开机启动
StartupTask::RequestEnableAsync 开启开机启动,并返回状态,可能失败。
StartupTaskState有三个值:(文档中显示有4个,没仔细查过)
- Disabled:表示禁用状态
- DisabledByUser:表示被用户手动禁用,比如:通过任务管理器禁用
- Enabled:表示启用
当处于DisabledByUser时,不可通过接口将其设置为Enabed状态。
遗留问题:
用QtCreator创建的Qt工程,再通过VS2015打开后不能编译通过,应该是需要在pro文件里添加额外的配置,暂时没有尝试去解决