380 lines
13 KiB
C++
Raw Normal View History


/**********************************************************************************
* @file SetupFuncLinux.cpp
* @brief Linux系统设置函数
* @author yikenan
* @versiong 1.0
* @date
**********************************************************************************/
//< 仅在Linux系统下编译
#ifdef OS_LINUX
#include <QtCore>
#include "SetupFunc.h"
#include "setupCommon.h"
#include <QStandardPaths>
#include <QProcess>
2025-03-13 15:19:38 +08:00
#include "setup/CommonDef.h"
2025-03-12 14:17:53 +08:00
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;
}
}
const QString desktopDir = getDesktopPath();
//< 注册系统服务,并设置自启动
bool regSysService(QString &strErr,QString path)
{
//< 判断服务是否已注册,普通用户权限可执行
2025-03-13 15:19:38 +08:00
if (0 == QProcess::execute(QString("systemctl is-enabled %1.service").arg(g_pszLauncherServiceName) ) )
{
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服务配置文件
{
2025-03-13 15:19:38 +08:00
QSettings objIniSetting(g_pszLauncherServiceFile, QSettings::IniFormat);
objIniSetting.setIniCodec( QTextCodec::codecForLocale() );
if (!objIniSetting.isWritable())
{
strErr = QObject::tr("服务配置文件不可写,请确认是否具有权限!")
2025-03-13 15:19:38 +08:00
+ "\n" + g_pszLauncherServiceFile;
return false;
}
//< 清空所有原有配置
objIniSetting.setFallbacksEnabled(false);
objIniSetting.clear();
objIniSetting.beginGroup("Unit");
2025-03-13 15:19:38 +08:00
objIniSetting.setValue("Description", g_pszLauncherServiceName);
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("写入服务配置文件失败!")
2025-03-13 15:19:38 +08:00
+ "\n" + g_pszLauncherServiceFile;
return false;
}
}
//< systemd重新加载配置文件
if (0 != QProcess::execute("systemctl daemon-reload"))
{
strErr = QObject::tr("调用系统重新加载配置失败!");
return false;
}
//< 设置服务开机自启动
2025-03-13 15:19:38 +08:00
if (0 != QProcess::execute(QString("systemctl enable %1.service").arg(g_pszLauncherServiceName) ))
{
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);
}
2025-03-13 15:19:38 +08:00
strCfgFileDir += g_pszXdgAutoStartCfgDir;
2025-03-13 15:19:38 +08:00
const QString strCfgFileFullPath = strCfgFileDir + g_pszHMIXdgDesktopCfgFile;
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对于GroupKey都是强制转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;
2025-03-13 15:19:38 +08:00
objStreamOut << "Name=" << g_pszHMIXdgDesktopName << 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;
2025-03-13 15:19:38 +08:00
// 用于窗体识别,解决某些桌面组件无法识别窗体而导致的问题
// 比如dash-to-dock上收藏的图标与运行的图标分离正常应该是一个图标
// 参见https://github.com/micheleg/dash-to-dock/issues/215
QString startupWMClass;
CDesktopEntry(const QString destopName_,const QString name_, const QString comment_, const QString exec_,
const QString icon_="", const QString startupWMClass_=""):
desktopName(destopName_),
name(name_),
comment(comment_),
exec(exec_),
2025-03-13 15:19:38 +08:00
icon(icon_),
startupWMClass(startupWMClass_)
{
}
};
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;
2025-03-13 15:19:38 +08:00
objStreamOut << "Exec=" << entry.exec <<endl;
objStreamOut << "Comment=" << entry.comment << endl;
2025-03-13 15:19:38 +08:00
if(!entry.icon.isEmpty())
objStreamOut << "Icon=" << entry.icon << endl;
2025-03-13 15:19:38 +08:00
if(!entry.startupWMClass.isEmpty())
objStreamOut << "StartupWMClass=" << entry.startupWMClass << endl;
objStreamOut << "Type=Application" << endl;
objStreamOut << "Categories=GNOME;Application;Other;Settings" << endl;
}
objFile.close();
}
QString chmodStr = QString("chmod +x ") + entryFileFullPath;
system(chmodStr.toStdString().c_str());
if(!isRoot)
{
QString username = qgetenv("SUDO_USER");
QString chownStr = QString("chown %1 ").arg(username) + entryFileFullPath;
system(chownStr.toStdString().c_str());
}
return true;
}
//< 创建快捷方式
bool creatShortcut(QString &strErr,QString path)
{
//<todo yikenan 路径需改动
const QString execProdDir = path + "/product/" + g_platform_dir_name;
const QString execPlatDir = path + "/platform/" + g_platform_dir_name;
2025-03-13 15:19:38 +08:00
const QString iconDir = path + "/resource/zh/setup/icons";
QDir appDir(g_pszAppDir);
appDir.mkdir(g_pszDesktopEntryDirName);
QString appDestPath = appDir.absoluteFilePath(g_pszDesktopEntryDirName);
if(!QDir(appDestPath).exists())
{
strErr = appDestPath + QObject::tr("不存在或无法创建");
return false;
}
2025-03-13 15:19:38 +08:00
createDesktopEntry(desktopDir,CDesktopEntry("sys_startup",QObject::tr("实时监控"),"system management",execProdDir+"/sys_startup",iconDir + "/sys_startup.ico", "sys_startup"),strErr,false);
return true;
}
bool createStartProgram(QString &strErr,const QString& path)
{
//<todo yikenan 路径需改动
const QString execProdDir = path + "/product/" + g_platform_dir_name;
const QString execPlatDir = path + "/platform/" + g_platform_dir_name;
2025-03-13 15:19:38 +08:00
const QString iconDir = path + "/resource/zh/setup/icons";
QDir appDir(g_pszAppDir);
appDir.mkdir(g_pszDesktopEntryDirName);
QString appDestPath = appDir.absoluteFilePath(g_pszDesktopEntryDirName);
if(!QDir(appDestPath).exists())
{
strErr = appDestPath + QObject::tr("不存在或无法创建");
return false;
}
createDesktopEntry(appDestPath,CDesktopEntry("sys_dog_auth_check", QObject::tr("超级狗检查"), "check system dog authentication",execProdDir+"/sys_dog_auth_check"),strErr);
2025-03-13 15:19:38 +08:00
createDesktopEntry(appDestPath,CDesktopEntry("FesSim", QObject::tr("前置调试"),"fes debug tool",execProdDir+"/FesSim",iconDir + "/fes_sim.ico"),strErr);
createDesktopEntry(appDestPath,CDesktopEntry("debug_tool", QObject::tr("工程调试工具"),"debug tool",execProdDir+"/debug_tool",iconDir + "/debug_tool.ico"),strErr);
createDesktopEntry(appDestPath,CDesktopEntry("sys_command",QObject::tr("命令窗口"),"bin exec environment",execProdDir+"/sys_command.sh"),strErr);
createDesktopEntry(appDestPath,CDesktopEntry("model_system_config",QObject::tr("系统建模"),"system model configuration",execPlatDir+"/model_system_config",iconDir + "/systemConfig.ico"),strErr);
createDesktopEntry(appDestPath,CDesktopEntry("model_studio",QObject::tr("设备建模"),"model studio",execPlatDir+"/model_studio",iconDir + "/studio.ico"),strErr);
createDesktopEntry(appDestPath,CDesktopEntry("hmi",QObject::tr("画面组态"),"human machine interface app",execPlatDir+"/hmi",iconDir + "/fes_sim.ico"),strErr);
createDesktopEntry(appDestPath,CDesktopEntry("fbd_editor",QObject::tr("逻辑编程"),"fbd editor",execPlatDir+"/fbd_designer",iconDir + "/fbd_editor.ico"),strErr);
createDesktopEntry(appDestPath,CDesktopEntry("db_manager",QObject::tr("工程管理"),"database management",execPlatDir+"/db_manager",iconDir + "/db_manager.ico"),strErr);
createDesktopEntry(appDestPath,CDesktopEntry("sys_startup",QObject::tr("实时监控"),"system management",execProdDir+"/sys_startup",iconDir + "/sys_startup.ico","sys_startup"),strErr);
createDesktopEntry(appDestPath,CDesktopEntry("hmi_explorer",QObject::tr("人机界面"),"open hmi",execPlatDir+"/hmi_explorer.sh"),strErr);
return true;
}
bool setSysctl()
{
system("echo 'net.ipv4.ping_group_range = 0 2147483647' > /etc/sysctl.d/555-ping.conf");
system("sysctl -p /etc/sysctl.d/555-ping.conf");
return true;
}
2025-03-13 15:19:38 +08:00
} //< namespace iot_sys
#endif //< #ifdef OS_LINUX