/********************************************************************************** * @file SetupFuncLinux.cpp * @brief Linux系统设置函数 * @author yikenan * @versiong 1.0 * @date **********************************************************************************/ //< 仅在Linux系统下编译 #ifdef OS_LINUX #include #include "SetupFunc.h" #include "setupCommon.h" #include #include namespace iot_sys { QString getDesktopPath() { QString username = qgetenv("SUDO_USER"); QProcess process; QString cmd = QString("su %1 -c \"xdg-user-dir DESKTOP\"").arg(username); process.start(cmd); process.waitForFinished(-1); // will wait forever until finished QString stdout = process.readAllStandardOutput().trimmed(); if( strcmp(g_iscs6000_os,"oe2203_aarch64") == 0 && stdout.isEmpty() ) { return QString("/home/%1/Desktop").arg(username); } else { return stdout; } } static const char *pszSystemdCfgFile = "/usr/lib/systemd/system/iscs6000_launcher.service"; //< 前面需加上用户HOME目录路径 static const char *pszXdgCfgDir = "/.config/autostart/"; static const char *pszXdgCfgFile = "iscs6000_hmi_explorer.desktop"; static const char *pszDesktopEntryDirName = "iscs6000"; static const char *pszAppDir = "/usr/share/applications"; const QString desktopDir = getDesktopPath(); //< 注册系统服务,并设置自启动 bool regSysService(QString &strErr,QString path) { //< 判断服务是否已注册,普通用户权限可执行 if (0 == QProcess::execute("systemctl is-enabled iscs6000_launcher.service")) { strErr = QObject::tr("已设置服务自启动,若需重新设置,请先取消!"); return false; } const QString strExec = path + "/platform/" + g_platform_dir_name + "/sys_launcher_srv"; //< 判断文件存在并设置可执行权限 if (QFile::exists(strExec)) { if(QFileDevice::ExeOther != (QFileDevice::ExeOther & QFile::permissions(strExec))) { QString strCmd = "chmod +x "; strCmd += strExec; if(0 != QProcess::execute(strCmd)) { strErr = QObject::tr("设置可执行权限失败!") + "\n" + strExec; return false; } } } else { strErr = QObject::tr("文件不存在!")+ "\n" + strExec; return false; } //< 生成或修改systemd服务配置文件 { QSettings objIniSetting(pszSystemdCfgFile, QSettings::IniFormat); objIniSetting.setIniCodec( QTextCodec::codecForLocale() ); if (!objIniSetting.isWritable()) { strErr = QObject::tr("服务配置文件不可写,请确认是否具有权限!") + "\n" + pszSystemdCfgFile; return false; } //< 清空所有原有配置 objIniSetting.setFallbacksEnabled(false); objIniSetting.clear(); objIniSetting.beginGroup("Unit"); objIniSetting.setValue("Description", "iscs6000_launcher"); objIniSetting.setValue("After", "network.target"); objIniSetting.endGroup(); objIniSetting.beginGroup("Service"); objIniSetting.setValue("Type", "simple"); objIniSetting.setValue("ExecStart", strExec); objIniSetting.setValue("KillMode", "process"); objIniSetting.setValue("Restart", "on-failure"); objIniSetting.setValue("RestartSec", "42s"); QString username = qgetenv("SUDO_USER"); if( !username.isEmpty() ) { objIniSetting.setValue("User",username); } objIniSetting.endGroup(); objIniSetting.beginGroup("Install"); objIniSetting.setValue("WantedBy", "multi-user.target"); objIniSetting.endGroup(); if (QSettings::NoError != objIniSetting.status()) { strErr = QObject::tr("写入服务配置文件失败!") + "\n" + pszSystemdCfgFile; return false; } } //< systemd重新加载配置文件 if (0 != QProcess::execute("systemctl daemon-reload")) { strErr = QObject::tr("调用系统重新加载配置失败!"); return false; } //< 设置服务开机自启动 if (0 != QProcess::execute("systemctl enable iscs6000_launcher.service")) { strErr = QObject::tr("设置服务开机自启动失败!"); return false; } return true; } //---------------------------------------- //< 设置HMI自启动 bool setHmiAutoStart(QString &strErr,QString path) { QString sudo_user = qgetenv("SUDO_USER"); QString user = qgetenv("USER"); QString strCfgFileDir; if(user == "root" && sudo_user.isEmpty()) { strCfgFileDir = "/root"; sudo_user = "root"; } else { strCfgFileDir = QString("/home/%1").arg(sudo_user); } strCfgFileDir += pszXdgCfgDir; const QString strCfgFileFullPath = strCfgFileDir + pszXdgCfgFile; if (QFile::exists(strCfgFileFullPath)) { strErr = QObject::tr("已设置HMI自启动,若需重新设置,请先取消!"); return false; } const QString strExec = path + "/product/" + g_platform_dir_name + "/sys_startup"; //< 判断文件存在并设置可执行权限 if (QFile::exists(strExec)) { if(QFileDevice::ExeOther != (QFileDevice::ExeOther & QFile::permissions(strExec))) { QString strCmd = "chmod +x "; strCmd += strExec; if(0 != QProcess::execute(strCmd)) { strErr = QObject::tr("设置可执行权限失败!") + "\n" + strExec; return false; } } } else { strErr = QObject::tr("文件不存在!") + "\n" + strExec; return false; } /* 启动器中的Group “Desktop Entry”,中间带有空格 而QSettings对于Group、Key都是强制转URL的,于是空格变成 %20 可是这样的写法,xdg不认 所以,不使用QSettings */ //< 生成或复写启动器文件 { //< 防止路径不存在,先建立 QDir objDir(strCfgFileDir); if(!objDir.exists()) { objDir.mkpath(strCfgFileDir); } QFile objFile(strCfgFileFullPath); if (!objFile.open(QIODevice::WriteOnly | QIODevice::Text)) { strErr = QObject::tr("启动器文件不可写,请确认是否具有权限!") + "\n" + strCfgFileFullPath; return false; } { QTextStream objStreamOut(&objFile); objStreamOut << "[Desktop Entry]" << endl; objStreamOut << "Name=iscs6000_hmi_explorer" << endl; objStreamOut << "Exec=" << strExec << endl; objStreamOut << "Type=Application" << endl; objStreamOut << "X-GNOME-AutoRestart=false" << endl; } objFile.close(); } QString stFilePerm = QString("chown -R %1:%1 %2").arg(sudo_user).arg(strCfgFileDir); system(stFilePerm.toStdString().c_str()); return true; } //---------------------------------------- class CDesktopEntry { public: QString desktopName; QString name; QString comment; QString exec; QString icon; CDesktopEntry(const QString destopName_,const QString name_, const QString comment_, const QString exec_, const QString icon_=""): desktopName(destopName_), name(name_), comment(comment_), exec(exec_), icon(icon_) { } }; bool createDesktopEntry(const QString &entrypath, const CDesktopEntry &entry, QString &strErr,bool isRoot = true) { const QString entryFileFullPath = entrypath + "/" + entry.desktopName + ".desktop"; //< 生成desktop文件 { QFile objFile(entryFileFullPath); if (!objFile.open(QIODevice::WriteOnly | QIODevice::Text)) { strErr = QObject::tr("快捷方式不可写,请确认是否具有权限!") + "\n" + entryFileFullPath; return false; } { QTextStream objStreamOut(&objFile); objStreamOut << "[Desktop Entry]" << endl; objStreamOut << "Name=" << entry.name << endl; objStreamOut << "Exec=sh -c \"export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/Qt5.9.9/5.9.9/gcc_64/lib;" << entry.exec << "\"" < /etc/sysctl.d/555-ping.conf"); system("sysctl -p /etc/sysctl.d/555-ping.conf"); return true; } } //< iot_sys #endif //< #ifdef OS_LINUX