2025-03-13 15:19:38 +08:00

380 lines
13 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**********************************************************************************
* @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>
#include "setup/CommonDef.h"
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)
{
//< 判断服务是否已注册,普通用户权限可执行
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服务配置文件
{
QSettings objIniSetting(g_pszLauncherServiceFile, QSettings::IniFormat);
objIniSetting.setIniCodec( QTextCodec::codecForLocale() );
if (!objIniSetting.isWritable())
{
strErr = QObject::tr("服务配置文件不可写,请确认是否具有权限!")
+ "\n" + g_pszLauncherServiceFile;
return false;
}
//< 清空所有原有配置
objIniSetting.setFallbacksEnabled(false);
objIniSetting.clear();
objIniSetting.beginGroup("Unit");
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("写入服务配置文件失败!")
+ "\n" + g_pszLauncherServiceFile;
return false;
}
}
//< systemd重新加载配置文件
if (0 != QProcess::execute("systemctl daemon-reload"))
{
strErr = QObject::tr("调用系统重新加载配置失败!");
return false;
}
//< 设置服务开机自启动
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);
}
strCfgFileDir += g_pszXdgAutoStartCfgDir;
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对于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=" << 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;
// 用于窗体识别,解决某些桌面组件无法识别窗体而导致的问题
// 比如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_),
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;
objStreamOut << "Exec=" << entry.exec <<endl;
objStreamOut << "Comment=" << entry.comment << endl;
if(!entry.icon.isEmpty())
objStreamOut << "Icon=" << entry.icon << endl;
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;
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(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;
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);
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;
}
} //< namespace iot_sys
#endif //< #ifdef OS_LINUX