实现程序开机自启动的方式


前言

开发应用程序时,会遇到需要程序能够开机自启的需求。本文介绍两种方式,来实现这一目的。


一、注册表

一般来说,遇到这种需求,我们首先想到的就是将应用程序的路径写到注册表来实现:

void setAutoStart(bool enable) {
    QString appName = QApplication::applicationName();  // 程序名称
    QString appPath = QApplication::applicationFilePath().replace("/","\\");  // 程序路径
    QSettings *reg = new QSettings("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", QSettings::NativeFormat);
    if (enable) {
        QString val = reg->value(appName).toString();  // 如果此键不存在,则返回的是空字符串
        if (val != appPath) {
            reg->setValue(appName,appPath);
        }
    } else {
        reg->remove(appName);
    }
    reg->deleteLater();
}

代码中实现了将应用程序路径写到注册表,同时也实现了从注册表删除该应用程序路径。如果程序是64位的,会写到:

计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run

若程序是32位的,则会被系统自动映射到:

计算机\HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Run

正常情况下,这样就实现了该应用程序的开机自启动。但是,如果应用程序是带有”盾牌“的(即UAC执行级别为requireAdministrator),如下图所示:

示例图片
示例图片

这时通过写注册表的方式,可能会出现开机没有自启动的问题。要解决这个问题,可以使用接下来要介绍的通过任务计划的方式。

二、任务计划

通过 Win+R 键,输入 taskschd.msc 可以打开任务计划界面:

示例图片

只要我们实现将应用程序写到这里,即可实现开机自启。代码如下:

void setAutoStart(bool enable) {
    QString appName = QApplication::applicationName();  // 程序名称
    QString appPath = QApplication::applicationFilePath().replace("/","\\");  // 程序路径
    appPath = "\"" + appPath + "\"";  // 路径要加引号
    QStringList arguments;
    if (enable) {
        arguments << "/create"
            << "/tn" << appName
            << "/tr" << appPath
            << "/sc" << "onlogon"
            << "/rl" << "highest"
            << "/f";
    } else {
        arguments << "/delete"
            << "/tn" << appName
            << "/f";
    }
    QProcess process;
    process.start("schtasks", arguments);
    process.waitForFinished();
    if (process.exitCode() != 0) {
        qDebug() << QString::fromLocal8Bit(process.readAllStandardError());
    }
}

这样就能在任务计划程序库中看到我们的应用程序了。双击它可以看到属性相关信息:

示例图片

看到其中这两项是默认勾选的:”如果任务运行时间超过以下时间,停止任务“和”如果请求后任务还在运行,强行将其停止“,我们要将这两项改成不勾选,所以最终的代码如下:

void setAutoStart(bool enable) {
    QString appName = QApplication::applicationName();  // 程序名称
    QString appPath = QApplication::applicationFilePath().replace("/","\\");  // 程序路径
    appPath = "\"" + appPath + "\"";  // 路径要加引号
    QStringList arguments;
    if (enable) {
        arguments << "/create"
            << "/tn" << appName
            << "/tr" << appPath
            << "/sc" << "onlogon"
            << "/rl" << "highest"
            << "/f";
    } else {
        arguments << "/delete"
            << "/tn" << appName
            << "/f";
    }
    QProcess process;
    process.start("schtasks", arguments);
    process.waitForFinished();
    if (process.exitCode() != 0) {
        qDebug() << QString::fromLocal8Bit(process.readAllStandardError());
    } else {
        if (enable) {
            // 配置计划任务的设置:1、禁用任务的执行时间限制 2、禁止系统强制终止任务
            QString psCommand = R"(
            $task = Get-ScheduledTask -TaskName ")" + appName + R"(";
            $task.Settings.ExecutionTimeLimit = "PT0S";
            $task.Settings.AllowHardTerminate = $false;
            Set-ScheduledTask $task;)";
            arguments.clear();
            arguments << "-ErrorAction" << "Stop" << "-Command" << psCommand;
            process.start("powershell", arguments);
            process.waitForFinished();
            if (process.exitCode() != 0) {
                qDebug() << QString::fromLocal8Bit(process.readAllStandardError());
            }
        }
    }
}

如果想要修改其他属性信息,也可以通过查阅相关资料来进行,这里不再赘述。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值