376 lines
13 KiB
C++
376 lines
13 KiB
C++
|
|
|
|||
|
|
/**********************************************************************************
|
|||
|
|
* @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>
|
|||
|
|
|
|||
|
|
namespace kbd_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 << "\"" <<endl;
|
|||
|
|
objStreamOut << "Comment=" << entry.comment << endl;
|
|||
|
|
if(entry.icon != "")
|
|||
|
|
objStreamOut << "Icon=" << entry.icon << 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 + "/product/common/resource/zh/setup/icons";
|
|||
|
|
QDir appDir(pszAppDir);
|
|||
|
|
appDir.mkdir(pszDesktopEntryDirName);
|
|||
|
|
QString appDestPath = appDir.absoluteFilePath(pszDesktopEntryDirName);
|
|||
|
|
if(!QDir(appDestPath).exists())
|
|||
|
|
{
|
|||
|
|
strErr = appDestPath + QObject::tr("不存在或无法创建");
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
createDesktopEntry(desktopDir,CDesktopEntry("sys_startup",QObject::tr("实时监控"),"iscs6000 system management",execProdDir+"/sys_startup",iconDir + "/sys_startup.ico"),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 + "/product/common/resource/zh/setup/icons";
|
|||
|
|
QDir appDir(pszAppDir);
|
|||
|
|
appDir.mkdir(pszDesktopEntryDirName);
|
|||
|
|
QString appDestPath = appDir.absoluteFilePath(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("前置调试"),"iscs6000 fes debug tool",execProdDir+"/FesSim",iconDir + "/fes_sim.ico"),strErr);
|
|||
|
|
createDesktopEntry(appDestPath,CDesktopEntry("debug_tool", QObject::tr("工程调试工具"),"iscs6000 debug tool",execProdDir+"/debug_tool",iconDir + "/debug_tool.ico"),strErr);
|
|||
|
|
createDesktopEntry(appDestPath,CDesktopEntry("sys_command",QObject::tr("命令窗口"),"iscs6000 bin exec environment",execProdDir+"/sys_command.sh"),strErr);
|
|||
|
|
createDesktopEntry(appDestPath,CDesktopEntry("model_system_config",QObject::tr("系统建模"),"iscs6000 system model configuration",execPlatDir+"/model_system_config",iconDir + "/systemConfig.ico"),strErr);
|
|||
|
|
createDesktopEntry(appDestPath,CDesktopEntry("model_studio",QObject::tr("设备建模"),"iscs6000 model studio",execPlatDir+"/model_studio",iconDir + "/studio.ico"),strErr);
|
|||
|
|
createDesktopEntry(appDestPath,CDesktopEntry("hmi",QObject::tr("画面组态"),"iscs6000 human machine interface app",execPlatDir+"/hmi",iconDir + "/fes_sim.ico"),strErr);
|
|||
|
|
createDesktopEntry(appDestPath,CDesktopEntry("fbd_editor",QObject::tr("逻辑编程"),"iscs6000 fbd editor",execPlatDir+"/fbd_designer",iconDir + "/fbd_editor.ico"),strErr);
|
|||
|
|
createDesktopEntry(appDestPath,CDesktopEntry("db_manager",QObject::tr("工程管理"),"iscs6000 database management",execPlatDir+"/db_manager",iconDir + "/db_manager.ico"),strErr);
|
|||
|
|
createDesktopEntry(appDestPath,CDesktopEntry("sys_startup",QObject::tr("实时监控"),"iscs6000 system management",execProdDir+"/sys_startup",iconDir + "/sys_startup.ico"),strErr);
|
|||
|
|
createDesktopEntry(appDestPath,CDesktopEntry("hmi_explorer",QObject::tr("人机界面"),"open iscs66000 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;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
} //< kbd_sys
|
|||
|
|
|
|||
|
|
#endif //< #ifdef OS_LINUX
|
|||
|
|
|
|||
|
|
|