开机启动的三种方式:
1.通过修改注册表实现
/**
* @brief AutoStart::setAutoStartByRegedit
* 编译成功后的exe就不需要用管理员方式运行也可以设置成功,打包到别的电脑也可以设置成功
*
* 操作成功后,可以在注册表中对应位置看到新增的键值对,不需要了则删除该键值对即可
*
* win + r 输入 regedit进入注册表,然后进入该目录 HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run
*
* 也可以通过代码QSettings进行删除
*/
bool AutoStart::setAutoStartByRegedit(const QString &strAppName, const QString &strExePath)
{
#ifdef _WIN32
#if AUTOSTARTTYPE== 1
// 注册表键路径
QString keyPath = "HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run";
// 使用QSettings来修改注册表
QSettings startupSettings(keyPath, QSettings::NativeFormat);
QString strPath = QDir::toNativeSeparators(strExePath);//不把路径改为windows风格,无法识别,会出现注册表写入成功,无法启动的现象
// 设置值
startupSettings.setValue(strAppName, strPath);
// 检查是否成功设置
if (startupSettings.value(strAppName) == strPath)
{
return true;
}
else
{
return false;
}
#endif
#endif
return false;
}
2.通过链接方式设置
/**
* @brief AutoStart::setAutoStartByLink
* 该方法不需要管理员权限,直接运行设置即可,可以在桌面看到一个快捷方式
* 以及在strAutoStartLink该路径下看到另一个快捷方式,用来自启的
* strAutoStartLink此路径存在后,后续如果有需要自启的程序放到该路径即可(已验证)
* 【注意该方法在win10下会被windows安全中心拦截,注意解除拦截信息】
*/
bool AutoStart::setAutoStartByLink(const QString &strAppName, const QString &strExePath)
{
#ifdef _WIN32
#if AUTOSTARTTYPE== 2
//建立开机启动快捷方式
QString strAutoStartType = QStandardPaths::writableLocation(QStandardPaths::StandardLocation::ApplicationsLocation) + "/Startup/";
//桌面快捷方式
QString strDesktopType = QStandardPaths::writableLocation(QStandardPaths::StandardLocation::DesktopLocation);
QDir autoStartDir(strAutoStartType);
if(!autoStartDir.exists())
{
if(!autoStartDir.mkpath(strAutoStartType))
{
return false;
}
}
//创建桌面快捷方式
QString strDesktopLink = strDesktopType + "/" + strAppName + ".lnk";
if(QFile::exists(strDesktopLink))
{
QFile::remove(strDesktopLink);//如果存在则先删除
}
QFile fApp(strExePath);
if(!fApp.link(strDesktopLink))
{
return false;
}
//创建自动启动的快捷方式
QString strAutoStartLink = strAutoStartType + strAppName + ".lnk";
if(QFile::exists(strAutoStartLink))
{
QFile::remove(strAutoStartLink);//如果存在则先删除
}
if(!fApp.link(strAutoStartLink))
{
return false;
}
return true;
#endif
#endif
return false;
}
通过启动计划实现
/**
* @brief AutoStart::setAutoStartByPlanTask
* 该方法需要用管理员权限运行该exe才可以运行成功,成功后在计划中可以看到该启动计划【不需要用管理员权限编译生成exe】
*
* win + r 输入 taskschd.msc进入计划管理程序 可以看到所有计划
*/
bool AutoStart::setAutoStartByPlanTask(const QString &strAppName, const QString &strExePath)
{
#ifdef _WIN32
#if AUTOSTARTTYPE== 3
QString strTaskPath = "schtasks";//win + r 输入 taskschd.msc
QString strTaskName = strAppName;
QProcess tmpProDel;//删除存在的任务
tmpProDel.start(strTaskPath,QStringList()<<"/delete"<<"/tn"<<strTaskName<<"/f");
tmpProDel.waitForFinished();
qDebug()<<tmpProDel.readAllStandardOutput();
qDebug()<<tmpProDel.readAllStandardError();
QProcess tmpCreate;//创建任务 //登录时启动 更多信息 cmd里面输入 schtasks /? 或者 schtasks /create /? 查看
tmpCreate.start(strTaskPath,QStringList()<<"/create"<<"/tn"<<strTaskName<<"/tr"<<strExePath<<"/sc"<<"ONLOGON");
tmpCreate.waitForFinished();
qDebug()<<tmpCreate.readAllStandardOutput();
qDebug()<<tmpCreate.readAllStandardError();
QProcess tmpProQuery;//查询该任务
tmpProQuery.start(strTaskPath,QStringList()<<"/query"<<"/tn"<<strTaskName);
tmpProQuery.waitForFinished();
QString strRes = tmpProQuery.readAllStandardOutput();
if(!strRes.contains(strTaskName))
{
return false;
}
return true;
#endif
#endif
return false;
}
程序以管理员方式启动
上述第三种方式可以结合管理员方式启动进行设置
#ifdef _WIN32
/**
* @brief Qt的方法参考:https://yyochq.smartapps.cn/pages/single/index?id=3256738&_swebfr=1&_swebFromHost=baiduboxapp
*/
//判断当前程序是否是管理员权限启动的,所以可以将需要管理员操作的内容封装起来通过此方法以普通用户权限进行调用exe,将其改为管理员权限的exe并启动
//linux下可以用 if(geteuid()==0)进行判断 #include <unistd.h>
if(!IsUserAnAdmin())
{
QString strPath = QCoreApplication::applicationFilePath();
strPath = QDir::toNativeSeparators(strPath);
// 以管理员权限,执行exe程序
//这种方式类似用QProcess启动一个外部程序,因为本案例是以此exe为启动程序,如果不返回,就有两个exe一个是管理员权限的,一个是普通权限的
HINSTANCE ins = ShellExecuteA(nullptr, "runas", strPath.toStdString().c_str(),
"runas", nullptr, SW_SHOWNORMAL);
//ShellExecuteEx功能比ShellExecuteA更强大
if (ins > (HINSTANCE)32)
{
return 0; // 程序新实例启动成功
}
}
#endif
备注:目前经过测试,上述三种方法,均需要登录才可以看到带界面的程序。并且第三种方式可以不登录启动,但是当你登录后界面程序不能显示,因为当你启动电脑时的用户为system,此时系统的ui交互功能并未开始,所以界面无法显示。