2025-03-12 10:03:16 +08:00
/**********************************************************************************
* @ 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-12 14:17:53 +08:00
namespace iot_sys
2025-03-12 10:03:16 +08:00
{
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 ;
}
2025-03-12 14:17:53 +08:00
} //< iot_sys
2025-03-12 10:03:16 +08:00
# endif //< #ifdef OS_LINUX