QT程序开机自启(Windows & Linux)
备注:程序无管理员权限运行。linux适配麒麟V10和中科方德系统(其它还未尝试, linux功能还可继续优化,后续在补充吧)
设置是否自启
void setAutoStart(bool flag)
{
#ifdef Q_OS_WIN
// 注册表路径需要使用双反斜杠,如果是32位系统,要使用QSettings::Registry32Format
#if 0
// 当前程序有管理权权限
QSettings settings("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", QSettings::Registry32Format);
#else
// 当前程序无管理权权限
QSettings settings("HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", QSettings::Registry32Format);
#endif
// 以程序名称作为注册表中的键
// 根据键获取对应的值(程序路径)
QString appName = QApplication::applicationName();
QString appPath = settings.value(appName).toString();
QString newPath = QDir::toNativeSeparators(QApplication::applicationFilePath());
if(flag){
// 如果注册表中的路径和当前程序路径不一样,
// 则表示没有设置自启动或自启动程序已经更换了路径
if (!bFilePathsEqual(appName, QApplication::applicationFilePath())) {
settings.setValue(appName, newPath);
}
}else{
settings.remove(appName);
}
#else
QFile rootAutoFile(QString("%1/%2").arg(_rootAutoPath).arg(qAppName() + ".desktop"));
QFile userAutoFile(QString("%1/%2").arg(_userAutoPath).arg(qAppName() + ".desktop"));
if(!userAutoFile.exists()){
QDir userAutoDir(_userAutoPath);
// 创建~/.config/autostart文件夹
!userAutoDir.exists() && userAutoDir.cdUp() && userAutoDir.mkdir("autostart");
bool copyFg = QFile::copy(rootAutoFile.fileName(), userAutoFile.fileName());
if(!copyFg) qCritical() << "copy autostart file failed" << rootAutoFile.fileName() << userAutoFile.fileName();
}
if(!rootAutoFile.exists()){
qCritical()<< rootAutoFile.fileName() + " is not exists";
}
if (!userAutoFile.open(QIODevice::ReadWrite | QIODevice::Text)) {
qWarning() << "无法打开文件" << userAutoFile.fileName();
return;
}
// 创建文本流
QTextStream in(&userAutoFile);
QString content = in.readAll();
QString searchString = QString("%1=%2").arg(_autoStartParm).arg(flag ? "false" : "true");
QString replaceString = QString("%1=%2").arg(_autoStartParm).arg(flag ? "true" : "false");
// 修改内容
if (content.contains(_autoStartParm)) {
content.replace(searchString, replaceString);
} else {
content += replaceString + "\n";
}
// 重写文件
userAutoFile.resize(0);
QTextStream out(&userAutoFile);
out << content;
userAutoFile.close();
#endif
}
判断是否自启
bool getAutoStart()
{
#ifdef Q_OS_WIN
// 注册表路径需要使用双反斜杠,如果是32位系统,要使用QSettings::Registry32Format
#if 0
// 当前程序有管理权权限
QSettings settings("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", QSettings::Registry32Format);
#else
// 当前程序无管理权权限
QSettings settings("HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", QSettings::Registry32Format);
#endif
QString appPath = settings.value(QApplication::applicationName()).toString();
return bFilePathsEqual(appPath, QApplication::applicationFilePath());
#else
QFile userAutoFile(QString("%1/%2").arg(_userAutoPath).arg(qAppName() + ".desktop"));
QFile rootAutoFile(QString("%1/%2").arg(_rootAutoPath).arg(qAppName() + ".desktop"));
auto findAutostart = [](const QString& fileName, const QString &parm) -> bool {
QFile file(fileName);
QTextStream stream(&file);
if(!file.open(QIODevice::ReadOnly | QIODevice::Text)){
qWarning() << "open file fail" << fileName;
return false;
}
QString content = stream.readAll();
file.close();
// 查询是否包含自启参数,未包含默认为自启状态
if (!content.contains(parm)) {
return true;
}
// 使用正则表达式查询自启参数的值
QRegularExpression regex(QString("%1=([^\\n\\r]*)").arg(parm));
auto match = regex.match(content);
if(match.hasMatch()){
return match.captured(1) == "true";
}
return false;
};
if(userAutoFile.exists()) {
return findAutostart(userAutoFile.fileName(), _autoStartParm);
}
if(rootAutoFile.exists()){
return findAutostart(rootAutoFile.fileName(), _autoStartParm);
}
qCritical()<<"autostart file no exists";
return false;
#endif
}
其它
// 判断俩个文件路径是否相同
bool bFilePathsEqual(const QString& path1, const QString& path2)
{
QFileInfo fileInfo1(path1);
QFileInfo fileInfo2(path2);
return fileInfo1.canonicalFilePath() == fileInfo2.canonicalFilePath();
}
#define MATE_DESKTOP_AUTOSTART_PARM "X-MATE-Autostart-enabled"
#define GNOME_DESKTOP_AUTOSTART_PARM "X-GNOME-Autostart-enabled"
#define KDE_DESKTOP_AUTOSTART_PARM "X-KDE-Autostart-enabled"
QString userConfigPath = QStandardPaths::writableLocation(QStandardPaths::StandardLocation::ConfigLocation);
QString desktopSerrion = qgetenv("DESKTOP_SESSION");
if(desktopSerrion.compare("lightdm-xsession", Qt::CaseInsensitive) == 0){
_autoStartParm = GNOME_DESKTOP_AUTOSTART_PARM;
}else if(desktopSerrion.compare(("mate"), Qt::CaseInsensitive) == 0){
_autoStartParm = MATE_DESKTOP_AUTOSTART_PARM;
}else{
_autoStartParm = MATE_DESKTOP_AUTOSTART_PARM;
}
_userAutoPath = QDir::cleanPath(userConfigPath + QDir::separator() + "autostart");
_rootAutoPath = "/etc/xdg/autostart";