Преглед на файлове

#IQRV #comment 支持普通调用版输入法的安装和卸载

gifur преди 2 години
родител
ревизия
700d4665ae

+ 218 - 246
Module/mod_ResourceWatcher/mod_ResourceWatcher.cpp

@@ -11,6 +11,8 @@
 #if defined(RVC_OS_LINUX)
 #include "SogouVersion.h"
 #include <winpr/sysinfo.h>
+#include <sys/wait.h>
+#include <errno.h>
 #endif //RVC_OS_LINUX
 
 #include "XUnZipZilb.h"
@@ -229,6 +231,50 @@ struct SogouInstallInfo
     }
 };
 
+std::string TryToGetSogouVersionEx()
+{
+    std::string succStr, errStr;
+    std::string runStr("cat /opt/sogouimebs/files/share/sogou-version");
+    if (SP::Module::Util::ShellExecute(runStr, succStr, errStr)) {
+        if (succStr.empty()) {
+            DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("cat sogou version return empty!");
+        } else {
+            DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("cat sogou version returned: %s", succStr.c_str());
+            return succStr;
+        }
+    } else {
+        DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("execute cmd failed: %s", errStr.c_str());
+    }
+    return "";
+}
+
+ErrorCodeEnum GetSogouInstallInfo(SogouInstallInfo& info)
+{
+    info.state.dwInstalledStatus = Sogou_GetInstallStatus();
+    info.state.strInstallDate = Sogou_GetInstallTime();
+    info.program.strInstallDir = Sogou_GetInstallPath();
+    info.program.strVersion = Sogou_GetVersion();
+    if (info.program.strVersion.IsNullOrEmpty()) {
+        info.program.strVersion = TryToGetSogouVersionEx().c_str();
+    }
+    const int maxTimes = 3;
+    int curTimes = 0;
+    while (info.state.dwInstalledStatus == 0 && info.program.strVersion.IsNullOrEmpty() && curTimes < maxTimes) {
+        Sleep(1000);
+        info.program.strVersion = Sogou_GetVersion();
+        if (info.program.strVersion.IsNullOrEmpty()) {
+            info.program.strVersion = TryToGetSogouVersionEx().c_str();
+        }
+        curTimes++;
+    }
+    DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%d, %s, %s, %s"
+                                                 , info.state.dwInstalledStatus, info.state.strInstallDate.GetData()
+                                                 , info.program.strInstallDir.GetData(), info.program.strVersion.GetData());
+    DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("InstallTime: %s", info.state.GetInstallTime().ToTimeString().GetData());
+
+    return info.IsInstalledSuccess() ? Error_Succeed : Error_InvalidState;
+}
+
 
 void ResourceWatcherEntity::UpdateDNS(SpReqAnsContext<ResourceWatcherService_UpdateDNS_Req, ResourceWatcherService_UpdateDNS_Ans>::Pointer ctx)
 {
@@ -325,23 +371,6 @@ void ResourceWatcherEntity::GetNetworkInfo(SpReqAnsContext<ResourceWatcherServic
     ctx->Answer(Error_Succeed);
 }
 
-std::string TryToGetSogouVersionEx()
-{
-    std::string succStr, errStr;
-    std::string runStr("cat /opt/sogouimebs/files/share/sogou-version");
-    if (SP::Module::Util::ShellExecute(runStr, succStr, errStr)) {
-        if (succStr.empty()) {
-            DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("cat sogou version return empty!");
-        } else {
-            DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("cat sogou version returned: %s", succStr.c_str());
-            return succStr;
-        }
-    } else {
-        DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("execute cmd failed: %s", errStr.c_str());
-    }
-    return "";
-}
-
 void ResourceWatcherEntity::GetThirdPartyInstallState(SpReqAnsContext<ResourceWatcherService_GetThirdPartyInstallState_Req, ResourceWatcherService_GetThirdPartyInstallState_Ans>::Pointer ctx)
 {
 
@@ -349,28 +378,7 @@ void ResourceWatcherEntity::GetThirdPartyInstallState(SpReqAnsContext<ResourceWa
 
     if (ctx->Req.mode == 1) {//查看搜狗输入法安装状态
         SogouInstallInfo info;
-        info.state.dwInstalledStatus = Sogou_GetInstallStatus();
-        info.state.strInstallDate = Sogou_GetInstallTime();
-        info.program.strInstallDir = Sogou_GetInstallPath();
-        info.program.strVersion = Sogou_GetVersion();
-        if (info.program.strVersion.IsNullOrEmpty()) {
-            info.program.strVersion = TryToGetSogouVersionEx().c_str();
-        }
-        const int maxTimes = 5;
-        int curTimes = 0;
-        while (info.state.dwInstalledStatus == 0 && info.program.strVersion.IsNullOrEmpty() && curTimes < maxTimes) {
-            Sleep(1200);
-            info.program.strVersion = Sogou_GetVersion();
-            if (info.program.strVersion.IsNullOrEmpty()) {
-                info.program.strVersion = TryToGetSogouVersionEx().c_str();
-            }
-            curTimes++;
-        }
-        Dbg("%d, %s, %s, %s"
-            , info.state.dwInstalledStatus, info.state.strInstallDate.GetData()
-            , info.program.strInstallDir.GetData(), info.program.strVersion.GetData());
-        Dbg("InstallTime: %s", info.state.GetInstallTime().ToTimeString().GetData());
-
+        GetSogouInstallInfo(info);
         ctx->Ans.status = info.IsInstalledSuccess() ? 1 : 0;
         ctx->Ans.reserverd1 = info.state.GetInstallTime().ToTimeString();
         ctx->Ans.path = info.program.strInstallDir;
@@ -425,7 +433,6 @@ void ResourceWatcherEntity::GetThirdPartyInstallState(SpReqAnsContext<ResourceWa
 ErrorCodeEnum SetFileExecutePriviledge(LPCTSTR lpcszDirOrFilePath)
 {
     ErrorCodeEnum result(Error_Succeed);
-
     if (ExistsDirA(lpcszDirOrFilePath)) {
         do 
         {
@@ -638,6 +645,7 @@ void ResourceWatcherEntity::InstallSogou(SpReqAnsContext<ResourceWatcherService_
 
     bool sogouInstalled = false;
     const bool doTryRestart = (ctx->Req.reserved1 != 1);
+    SogouInstallInfo info;
 
     //安装搜狗输入法
     bool zipFind = false;
@@ -649,18 +657,20 @@ void ResourceWatcherEntity::InstallSogou(SpReqAnsContext<ResourceWatcherService_
     GetFunction()->GetPath("Temp", strTempDirPath);
 
     if (strDownloadDirPath.IsNullOrEmpty()) {
+        DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("downloads path is invalid, maybe in config mode");
         tmpResult = Error_Unexpect;
         tmpMsg = CSimpleStringA::Format("搜狗安装包目录[Downloads]不存在!");
     }
-    else
-    {
+    else {
         DIR* dp;
         struct dirent* dirp;
+        DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("to open dir %s", strDownloadDirPath.GetData());
         if ((dp = opendir(strDownloadDirPath.GetData())) != NULL)
         {
             while ((dirp = readdir(dp)) != NULL)
             {
                 CSimpleStringA tmpName(dirp->d_name);
+                DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("name:%s", tmpName.GetData());
                 if ((tmpName.IsStartWith("sogou", true) || tmpName.IsStartWith("uos-sogou", true))
                     && tmpName.IsEndWith(".zip", true)) {
 
@@ -668,7 +678,7 @@ void ResourceWatcherEntity::InstallSogou(SpReqAnsContext<ResourceWatcherService_
                     memset(&buf, 0x00, sizeof(buf));
                     const int ret = stat(CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s", strDownloadDirPath.GetData(), dirp->d_name).GetData(), &buf);
                     if (ret != 0) {
-                        Dbg("获取文件[%s]状态信息出错。", tmpName.GetData());
+                        DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("获取文件[%s]状态信息出错。", tmpName.GetData());
                     }
                     else if (buf.st_mtim.tv_sec > newestWrite) {
                         newestWrite = buf.st_mtim.tv_sec;
@@ -677,9 +687,7 @@ void ResourceWatcherEntity::InstallSogou(SpReqAnsContext<ResourceWatcherService_
                     }
                 }
             }
-
             closedir(dp);
-
             if (!zipFind)
             {
                 tmpResult = Error_NotExist;
@@ -696,7 +704,8 @@ void ResourceWatcherEntity::InstallSogou(SpReqAnsContext<ResourceWatcherService_
     CSimpleStringA strInstallPkgPath(true);
     if (zipFind)
     {
-        if (UnzipPack(newSogouPath.GetData()) != Error_Succeed)
+        DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("to unzip pack %s", newSogouPath.GetData());
+        if (UnzipPack(newSogouPath) != Error_Succeed)
         {
             tmpResult = Error_Unexpect;
             tmpMsg = CSimpleStringA::Format("解压搜狗安装包失败!");
@@ -716,112 +725,66 @@ void ResourceWatcherEntity::InstallSogou(SpReqAnsContext<ResourceWatcherService_
         }
     }
 
-
     CSimpleStringA strInstallScriptFile;
     CSimpleStringA strRunIniFilePath;
     CSimpleStringA strResultLogFilePath;
-    Dbg("to install sogou input...");
     const bool doNotStartup(true); //安装后是否启动搜狗输入法服务,据搜狗反馈,不能通过root权限启动Sogou输入法
     if (tmpResult == Error_Succeed)
     {
+        DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("to install sogou input... %s", strInstallPkgPath.GetData());
         tmpResult = SetFileExecutePriviledge(strInstallPkgPath);
         if (tmpResult != Error_Succeed) {
             tmpMsg = CSimpleStringA::Format("%s 修改文件夹权限失败", strInstallPkgPath.GetData());
             tmpResult = Error_NotExist;
 
-        }
-        else {
-            DIR* dp1;
-            struct dirent* dirp1;
-            if ((dp1 = opendir(strTempDirPath.GetData())) != NULL) {
+        } else {
 
-                while ((dirp1 = readdir(dp1)) != NULL)
-                {
-                    CSimpleStringA tmpName(dirp1->d_name);
-                    if (tmpName.IsStartWith("sogou", true) || tmpName.IsStartWith("uos-sogou", true))
-                    {
-                        strRunIniFilePath = strInstallPkgPath + SPLIT_SLASH_STR + tmpName + SPLIT_SLASH_STR + "Run.ini";
-                        strResultLogFilePath = strInstallPkgPath + SPLIT_SLASH_STR + tmpName + SPLIT_SLASH_STR + "result.log";
-                        if (ExistsFileA(strRunIniFilePath)) {
-                            char* p = inifile_read_str(strRunIniFilePath, "Action", "ToRun", "");
-                            strInstallScriptFile = strInstallPkgPath + SPLIT_SLASH_STR + tmpName + SPLIT_SLASH_STR + p;
-                            toolkit_free(p);
-                        }
-                        else
-                        {
-                            strInstallScriptFile = strInstallPkgPath + SPLIT_SLASH_STR + tmpName + SPLIT_SLASH_STR + "install_sogouime.sh";
-                        }
-                    }
-                }
-                closedir(dp1);
-            }
-            else
-            {
-                DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM) ("Temp files FindFirstFile failed");
-                return;
+            strRunIniFilePath = strInstallPkgPath + SPLIT_SLASH_STR + "Run.ini";
+            strResultLogFilePath = strInstallPkgPath + SPLIT_SLASH_STR + "result.log";
+            if (ExistsFileA(strRunIniFilePath)) {
+                char* p = inifile_read_str(strRunIniFilePath, "Action", "ToRun", "");
+                strInstallScriptFile = strInstallPkgPath + SPLIT_SLASH_STR + p;
+                FREE(p);
+            } else {
+                strInstallScriptFile = strInstallPkgPath + SPLIT_SLASH_STR + "install_sogouime.sh";
             }
 
-            Dbg("install script file: %s", strInstallScriptFile.GetData());
+            DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("install script file: %s", strInstallScriptFile.GetData());
             if (ExistsFileA(strInstallScriptFile)) {
                 char app[MAX_PATH] = { '\0' };
                 sprintf(app, "bash %s", strInstallScriptFile.GetData());
                 tmpResult = RunShellScript(app);
                 if (tmpResult != 0) {
                     tmpMsg = CSimpleStringA::Format("执行 '%s' 失败", app);
-                }
-                else if (!doNotStartup) {
+
+                } else if (!doNotStartup) {
+
                     CSimpleStringA strStartupScriptFile(strInstallPkgPath + SPLIT_SLASH_STR + "startup_service.sh");
-                    Dbg("startup script file: %s", strStartupScriptFile.GetData());
+                    DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("startup script file: %s", strStartupScriptFile.GetData());
                     if (!ExistsFileA(strStartupScriptFile)) {
                         tmpMsg = CSimpleStringA::Format("%s 启动脚本文件不存在,请重启设备再次验证", strStartupScriptFile.GetData());
                         tmpResult = Error_NotExist;
-                    }
-                    else {
+                    } else {
                         Sleep(1000);
                         do {
-                            char app[MAX_PATH] = { '\0' };
-                            tk_process_t* process = NULL;
-                            tk_process_option_t option;
-                            option.exit_cb = NULL;
-                            option.file = NULL;
-                            option.flags = 0;
-#if 0
-                            auto users = GetUserNameList(true);
-                            if (users.size() == 1) {
-                                sprintf(app, "su -m -p -c \"bash %s\" %s", strStartupScriptFile.GetData(), users[0].c_str());
-                            }
-                            else {
-                                for (auto it = users.cbegin(); it != users.cend(); ++it) {
-                                    Dbg("user:%s", it->c_str());
-                                }
-                                sprintf(app, "bash %s", strStartupScriptFile.GetData());
-                            }
-#else
                             sprintf(app, "bash %s", strStartupScriptFile.GetData());
-#endif
-                            option.params = app;
-                            const int res = process_spawn(&option, &process);
-                            if (0 == res) {
-                                FREE(process);
-                                Dbg("execute {%s} suc", app);
-                            }
-                            else {
-                                tmpMsg = CSimpleStringA::Format("执行 '%s' 失败:%s", app, toolkit_strerror(res));
+                            tmpResult = RunShellScript(app);
+                            if (tmpResult != 0) {
+                                tmpMsg = CSimpleStringA::Format("执行 '%s' 失败", app);
                                 tmpResult = Error_Process;
                             }
                         } while (false);
                     }
                 }
-            }
-            else {
+            } else {
                 tmpMsg = CSimpleStringA::Format("%s 执行文件不存在", strInstallScriptFile.GetData());
                 tmpResult = Error_NotExist;
             }
         }
+
     }
     if (tmpResult == Error_Succeed) {
         Sleep(1500);
-        //const CSimpleStringA strResultLogFilePath = strInstallPkgPath + SPLIT_SLASH_STR + "result.log";
         do
         {
             const int maxTimes = 5;
@@ -855,43 +818,21 @@ void ResourceWatcherEntity::InstallSogou(SpReqAnsContext<ResourceWatcherService_
                         tmpMsg = CSimpleStringA::Format("%s", szTmp);
                     }
                     else {
-                        SogouInstallInfo info;
-                        info.state.dwInstalledStatus = Sogou_GetInstallStatus();
-                        info.state.strInstallDate = Sogou_GetInstallTime();
-                        info.program.strInstallDir = Sogou_GetInstallPath();
-                        info.program.strVersion = Sogou_GetVersion();
-                        if (info.program.strVersion.IsNullOrEmpty()) {
-                            info.program.strVersion = TryToGetSogouVersionEx().c_str();
+                        GetSogouInstallInfo(info);
+                        if (!info.IsInstalledSuccess()) {
+                            tmpResult = Error_FailVerify;
+                            tmpMsg = CSimpleStringA::Format("检测安装状态失败!");
                         }
-                        const int maxTimes = 5;
-                        int curTimes = 0;
-                        while (!doNotStartup && info.state.dwInstalledStatus == 0 && info.program.strVersion.IsNullOrEmpty() && curTimes < maxTimes) {
-                            Sleep(1200);
-                            info.program.strVersion = Sogou_GetVersion();
-                            if (info.program.strVersion.IsNullOrEmpty()) {
-                                info.program.strVersion = TryToGetSogouVersionEx().c_str();
-                            }
-                            curTimes++;
-                        }
-                        Dbg("InstallTime: %s", info.state.GetInstallTime().ToTimeString().GetData());
-                        Dbg("%d, %s, %s, %s"
-                            , info.state.dwInstalledStatus, info.state.strInstallDate.GetData()
-                            , info.program.strInstallDir.GetData(), info.program.strVersion.GetData());
-
-                    if (!info.IsInstalledSuccess()) {
-                        tmpResult = Error_FailVerify;
-                        tmpMsg = CSimpleStringA::Format("检测安装状态失败!");
-                    }
-                    else {
-                        ctx->Ans.path = info.program.strInstallDir;
-                        ctx->Ans.reserverd1 = info.program.strVersion;
-                        ctx->Ans.reserverd2 = info.state.GetInstallTime().ToTimeString();
+                        else {
+                            ctx->Ans.path = info.program.strInstallDir;
+                            ctx->Ans.reserverd1 = info.program.strVersion;
+                            ctx->Ans.reserverd2 = info.state.GetInstallTime().ToTimeString();
 
-                        if (doTryRestart) {
-                            tmpMsg = CSimpleStringA::Format(" 从[%s]安装搜狗输入法成功,设备即将重启。", strInstallPkgPath.GetData());
+                            if (doTryRestart) {
+                                tmpMsg = CSimpleStringA::Format(" 从[%s]安装搜狗输入法成功,设备即将重启。", strInstallPkgPath.GetData());
+                            }
+                            sogouInstalled = true;
                         }
-                        sogouInstalled = true;
-                    }
                 }
             }
         }
@@ -901,22 +842,8 @@ void ResourceWatcherEntity::InstallSogou(SpReqAnsContext<ResourceWatcherService_
     ctx->Ans.msg = tmpMsg;
     ctx->Answer(result);
 
-    CVersion installVer;
-    DWORD dwMajor(0), dwMinor(0), dwRevision(0), dwBuild(0);
-    int n = sscanf(ctx->Ans.reserverd1.GetData(), "%d.%d.%d.%d", &dwMajor, &dwMinor, &dwRevision, &dwBuild);
-    if (n != 4)
-    {
-        DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("Not sogou version.[%s]", ctx->Ans.reserverd1.GetData());
-    }
-    else
-    {
-        installVer = CVersion(dwMajor, dwMinor, dwRevision, dwBuild);
-    }
-    CVersion standardVer = CVersion(2, 6, 4, 355); //对比版本为2.4.6.355
-
 
-    if (sogouInstalled && doTryRestart && installVer < standardVer)
-    {
+    if (sogouInstalled && doTryRestart && !info.program.IsTSFVersion()) {
         HealthManagerService_ClientBase* m_pRWClient = new HealthManagerService_ClientBase(this);
         ErrorCodeEnum eErr = m_pRWClient->Connect();
 
@@ -924,20 +851,15 @@ void ResourceWatcherEntity::InstallSogou(SpReqAnsContext<ResourceWatcherService_
             Dbg("HealthManager connected failed.");
             m_pRWClient->SafeDelete();
             m_pRWClient = NULL;
-        }
-        else
-        {
+        } else {
             HealthManagerService_ControlTerminalLife_Req detReq;
             HealthManagerService_ControlTerminalLife_Ans detAns;
             detReq.cmdType = 4;
             detReq.reason = 0;
             eErr = m_pRWClient->ControlTerminalLife(detReq, detAns, 3000);
-            if (eErr == Error_Succeed)
-            {
+            if (eErr == Error_Succeed) {
                 LogWarn(Severity_Low, Error_Debug, LOG_RESOURCEWATCHE_RESTARTPC_AFTER_INSTALLED_SOGOUINPUT, "Ask HealthManagerService for restarting PC succ after installing sogouinput");
-            }
-            else
-            {
+            } else {
                 LogWarn(Severity_Middle, Error_Unexpect, 0, CSimpleStringA::Format("HealthManagerService::ControlTerminalLife failed: %s", SpStrError(eErr)));
             }
             m_pRWClient->GetFunction()->CloseSession();
@@ -946,6 +868,87 @@ void ResourceWatcherEntity::InstallSogou(SpReqAnsContext<ResourceWatcherService_
     }
 }
 
+void ResourceWatcherEntity::UninstallSogou(SpReqAnsContext<ResourceWatcherService_UninstallThirdPartyProgram_Req, ResourceWatcherService_UninstallThirdPartyProgram_Ans>::Pointer ctx)
+{
+    ErrorCodeEnum result(Error_Succeed);
+    ErrorCodeEnum tmpResult(Error_Succeed);
+    CSimpleStringA tmpMsg(true);
+
+    DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("to uninstall sogou input...");
+    CSimpleStringA strUninstallScriptFile(true);
+    SogouInstallInfo info;
+    do {
+        ErrorCodeEnum ecGet = GetSogouInstallInfo(info);
+        if (info.program.IsTSFVersion()) {
+            CSimpleStringA shellScriptPath;
+            GetFunction()->GetPath("Base", shellScriptPath);
+            shellScriptPath += SPLIT_SLASH_STR;
+            shellScriptPath += "res" SPLIT_SLASH_STR "RunScript" SPLIT_SLASH_STR;
+            strUninstallScriptFile = shellScriptPath + "uninstall_tfs_sogouimebs.sh";
+            if (!ExistsFileA(strUninstallScriptFile)) {
+                tmpMsg = CSimpleStringA::Format("%s 文件不存在!", strUninstallScriptFile.GetData());
+                tmpResult = Error_InvalidState;
+                break;
+            }
+            char app[MAX_PATH] = { '\0' };
+            sprintf(app, "bash %s", strUninstallScriptFile.GetData());
+            tmpResult = RunShellScript(app);
+            if (tmpResult != 0) {
+                tmpMsg = CSimpleStringA::Format("执行 '%s' 失败", app);
+            } else {
+                Sleep(300);
+            }
+        } else {
+            CSimpleStringA strInstallPkgPath;
+            tmpResult = GetSogouPkgDirPath(strInstallPkgPath);
+            if (tmpResult == Error_Succeed) {
+                tmpResult = SetFileExecutePriviledge(strInstallPkgPath);
+                if (tmpResult != Error_Succeed) {
+                    tmpMsg = CSimpleStringA::Format("%s 修改文件夹权限失败", strInstallPkgPath.GetData());
+                    tmpResult = Error_NoPrivilege;
+                    break;
+                }
+                const CSimpleStringA strShutdownScriptFile = strInstallPkgPath + SPLIT_SLASH_STR + "shutdown_service.sh";
+                strUninstallScriptFile = strInstallPkgPath + SPLIT_SLASH_STR + "uninstall_sogouime.sh";
+                if (!ExistsFileA(strShutdownScriptFile)) {
+                    tmpMsg = CSimpleStringA::Format("%s 文件不存在!", strShutdownScriptFile.GetData());
+                    tmpResult = Error_InvalidState;
+                    break;
+                }
+                if (!ExistsFileA(strUninstallScriptFile)) {
+                    tmpMsg = CSimpleStringA::Format("%s 文件不存在!", strUninstallScriptFile.GetData());
+                    tmpResult = Error_InvalidState;
+                    break;
+                }
+                char app[MAX_PATH] = { '\0' };
+                sprintf(app, "bash %s", strShutdownScriptFile.GetData());
+                tmpResult = RunShellScript(app);
+                if (tmpResult != 0) {
+                    tmpMsg = CSimpleStringA::Format("执行 '%s' 失败", app);
+                } else {
+                    Sleep(300);
+                    sprintf(app, "bash %s", strUninstallScriptFile.GetData());
+                    tmpResult = RunShellScript(app);
+                    if (tmpResult != 0) {
+                        tmpMsg = CSimpleStringA::Format("执行 '%s' 失败", app);
+                    } else {
+                        Sleep(100);
+                    }
+                }
+            } else {
+                tmpMsg = CSimpleStringA::Format(" 指定位置 [Ad] 找不到输入法安装包");
+                tmpResult = Error_InvalidState;
+                break;
+            }
+        }
+
+    } while (false);
+
+    ctx->Ans.result = tmpResult;
+    ctx->Ans.msg = tmpMsg;
+    ctx->Answer(result);
+}
+
 void ResourceWatcherEntity::GetTerminalVersionList(SpReqAnsContext<ResourceWatcherService_GetTerminalVersionList_Req, ResourceWatcherService_GetTerminalVersionList_Ans>::Pointer ctx)
 {
     CSimpleStringA strVersionBaseDir(true);
@@ -1119,50 +1122,17 @@ void ResourceWatcherEntity::UninstallThirdPartyProgram(SpReqAnsContext<ResourceW
     ErrorCodeEnum tmpResult(Error_Succeed);
     CSimpleStringA tmpMsg(true);
 
-    LogWarn(Severity_Low, Error_Debug, LOG_RESOURCEWATCHE_UNINSTALL_THIRDPARTYPROGRAM, CSimpleStringA::Format("UninstallThirdPartyProgram: ctx-req context: %d, %d, %d", ctx->Req.type, ctx->Req.reserved1, ctx->Req.reserved2));
+    LogWarn(Severity_Low, Error_Debug, LOG_RESOURCEWATCHE_UNINSTALL_THIRDPARTYPROGRAM, 
+            CSimpleStringA::Format("UninstallThirdPartyProgram: ctx-req context: %d, %d, %d", ctx->Req.type, ctx->Req.reserved1, ctx->Req.reserved2));
 
     if (ctx->Req.type == 1) {
-        Dbg("to uninstall sogou input...");
-        CSimpleStringA strInstallPkgPath;
-        tmpResult = GetSogouPkgDirPath(strInstallPkgPath);
-        if (tmpResult == Error_Succeed) {
-            do 
-            {
-                tmpResult = SetFileExecutePriviledge(strInstallPkgPath);
-                if (tmpResult != Error_Succeed) {
-                    tmpMsg = CSimpleStringA::Format("%s 修改文件夹权限失败", strInstallPkgPath.GetData());
-                    tmpResult = Error_NoPrivilege;
-                    break;
-                }
-                const CSimpleStringA strShutdownScriptFile = strInstallPkgPath + SPLIT_SLASH_STR + "shutdown_service.sh";
-                const CSimpleStringA strUninstallScriptFile = strInstallPkgPath + SPLIT_SLASH_STR + "uninstall_sogouime.sh";
-                if (!ExistsFileA(strShutdownScriptFile)) {
-                    tmpMsg = CSimpleStringA::Format("%s 文件不存在!", strShutdownScriptFile.GetData());
-                    tmpResult = Error_InvalidState;
-                    break;
-                }
-                if (!ExistsFileA(strUninstallScriptFile)) {
-                    tmpMsg = CSimpleStringA::Format("%s 文件不存在!", strUninstallScriptFile.GetData());
-                    tmpResult = Error_InvalidState;
-                    break;
-                }
-                char app[MAX_PATH] = { '\0' };
-                sprintf(app, "bash %s", strShutdownScriptFile.GetData());
-                tmpResult = RunShellScript(app);
-                if (tmpResult != 0) {
-                    tmpMsg = CSimpleStringA::Format("执行 '%s' 失败", app);
-                } else {
-                    Sleep(300);
-                    sprintf(app, "bash %s", strUninstallScriptFile.GetData());
-                    tmpResult = RunShellScript(app);
-                    if (tmpResult != 0) {
-                        tmpMsg = CSimpleStringA::Format("执行 '%s' 失败", app);
-                    } else {
-                        Sleep(100);
-                    }
-                }
-            } while (false);
-        }
+
+        //安装搜狗输入法
+        UninstallSogouTask* sogouUninstall = new UninstallSogouTask(this);
+        sogouUninstall->ctx = ctx;
+        GetFunction()->PostThreadPoolTask(sogouUninstall);
+        return;
+
     } else {
         result = Error_NotSupport;
     }
@@ -1184,13 +1154,7 @@ void ResourceWatcherEntity::RestartThirdPartyProgram(SpReqAnsContext<ResourceWat
     if (ctx->Req.type == 1) 
     {
         SogouInstallInfo info;
-        info.state.dwInstalledStatus = Sogou_GetInstallStatus();
-        info.state.strInstallDate = Sogou_GetInstallTime();
-        info.program.strInstallDir = Sogou_GetInstallPath();
-        info.program.strVersion = Sogou_GetVersion();
-        if (info.program.strVersion.IsNullOrEmpty()) {
-            info.program.strVersion = TryToGetSogouVersionEx().c_str();
-        }
+        GetSogouInstallInfo(info);
 
         if (!info.program.IsTSFVersion())
         {
@@ -1520,29 +1484,7 @@ ErrorCodeEnum ResourceWatcherEntity::DoCheckInstallStateJob()
     if (ERROR_FILE_NOT_FOUND == GetSogouExecuteInfo(info.program, is32Bit))
         GetSogouExecuteInfo(info.program, !is32Bit);
 #else
-    info.state.dwInstalledStatus = Sogou_GetInstallStatus();
-    info.state.strInstallDate = Sogou_GetInstallTime();
-    info.program.strInstallDir = Sogou_GetInstallPath();
-    info.program.strVersion = Sogou_GetVersion();
-    if (info.program.strVersion.IsNullOrEmpty()) {
-        info.program.strVersion = TryToGetSogouVersionEx().c_str();
-    }
-    /** 重试获取版本号 [Gifur@2022224]*/
-    const int maxTimes = 3;
-    int curTimes = 0;
-    while (info.state.dwInstalledStatus == 0 && info.program.strVersion.IsNullOrEmpty() && curTimes < maxTimes) {
-        Sleep(1500);
-        info.program.strVersion = Sogou_GetVersion();
-        if (info.program.strVersion.IsNullOrEmpty()) {
-            info.program.strVersion = TryToGetSogouVersionEx().c_str();
-        }
-        curTimes++;
-    }
-
-    Dbg("%d, %s, %s, %s"
-        , info.state.dwInstalledStatus, info.state.strInstallDate.GetData()
-        , info.program.strInstallDir.GetData(), info.program.strVersion.GetData());
-    Dbg("InstallTime: %s", info.state.GetInstallTime().ToTimeString().GetData());
+    GetSogouInstallInfo(info);
 #endif //RVC_OS_WIN
 
     CSimpleStringA strLastRecord(true);
@@ -1769,7 +1711,7 @@ ErrorCodeEnum ResourceWatcherEntity::GetSogouPkgDirPath(CSimpleStringA& strPkgPa
         for (int i = 0; i < subs->nelts; ++i) {
             char* dir = ARRAY_IDX(subs, i, char*);
             const char* dirname = &dir[strAdDataDirPath.GetLength() + 1];
-            if (CSimpleStringA(dirname).IsStartWith("sogou", true)) {
+            if (CSimpleStringA(dirname).IsStartWith("sogou", true) || CSimpleStringA(dirname).IsStartWith("uos-sogou", true)) {
                 if (strInstallPkgPath.IsNullOrEmpty()) {
                     Dbg("found it: %s", dir);
                     strInstallPkgPath = dir;
@@ -1789,23 +1731,53 @@ ErrorCodeEnum ResourceWatcherEntity::GetSogouPkgDirPath(CSimpleStringA& strPkgPa
     return Error_Succeed;
 }
 
-///**TODO(Gifur@8/11/2023): 合并单屏版本,去除bin目录的干扰 */
 ErrorCodeEnum ResourceWatcherEntity::RunShellScript(LPCTSTR cmdline)
 {
     char app[MAX_PATH] = { '\0' };
+    char szldPath[1024] = { '\0' };
+    size_t szldLen = 1023;
+
     tk_process_t* process = NULL;
     tk_process_option_t option;
+
+    const int ldRet = toolkit_getenv("LD_LIBRARY_PATH", szldPath, &szldLen);
+    if (ldRet == 0) {
+        DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("get library path: %s", szldPath);
+        toolkit_unsetenv("LD_LIBRARY_PATH");
+    } else {
+        DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("GetEnv of LD_LIBRARY_PATH failed: %s", toolkit_strerror(ldRet));
+    }
+
     option.exit_cb = NULL;
     option.file = NULL;
     option.flags = 0;
     option.params = (char*)cmdline;
     const int res = process_spawn(&option, &process);
+
+    if (ldRet == 0) {
+        toolkit_setenv("LD_LIBRARY_PATH", szldPath);
+    }
+
     if (0 == res) {
-        DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("execute {%s}, pid: %d", cmdline, process->pid);
+        DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("execute {%s}, pid: %d, and wait ...", cmdline, process->pid);
+        int status;
+        while (process->pid > 0 && waitpid(process->pid, &status, 0) < 0) {
+            if (errno != EINTR) {
+                status = -1;
+                break;
+            }
+        }
+        if (WIFEXITED(status)) {
+            DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("normal terminal. exit status: %d", WEXITSTATUS(status));
+        } else if (WIFSIGNALED(status)) {
+            DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("abnormal terminal, signal: %d", WTERMSIG(status));
+        } else if (WIFSTOPPED(status)) {
+            DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("cihild stop, signal: %d", WSTOPSIG(status));
+        }
         FREE(process);
         return Error_Succeed;
     } else {
-        DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("execute {%s} failed: %d", cmdline, res);
+        DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("execute {%s} failed: %d", cmdline, res);
         return Error_Unexpect;
     }
 }

+ 16 - 0
Module/mod_ResourceWatcher/mod_ResourceWatcher.h

@@ -298,6 +298,9 @@ public:
 	void InstallSogou(SpReqAnsContext<ResourceWatcherService_InstallThirdPartyProgram_Req,
 		ResourceWatcherService_InstallThirdPartyProgram_Ans>::Pointer ctx);
 
+    void UninstallSogou(SpReqAnsContext<ResourceWatcherService_UninstallThirdPartyProgram_Req,
+					  ResourceWatcherService_UninstallThirdPartyProgram_Ans>::Pointer ctx);
+
 	virtual void OnSysVarEvent(const char* pszKey, const char* pszValue, const char* pszOldValue, const char* pszEntityName);
 
 #if defined(_MSC_VER)
@@ -390,4 +393,17 @@ struct InstallSogouTask : public ITaskSp
 	{
 		m_pEntity->InstallSogou(ctx);
 	}
+};
+
+struct UninstallSogouTask : public ITaskSp
+{
+    SpReqAnsContext<ResourceWatcherService_UninstallThirdPartyProgram_Req,
+        ResourceWatcherService_UninstallThirdPartyProgram_Ans>::Pointer ctx;
+
+    ResourceWatcherEntity* m_pEntity;
+	UninstallSogouTask(ResourceWatcherEntity* entity) :m_pEntity(entity) {}
+    void Process()
+    {
+        m_pEntity->UninstallSogou(ctx);
+    }
 };

+ 1 - 1
Module/mod_healthmanager/mod_healthmanager.cpp

@@ -3518,7 +3518,7 @@ void CHealthManagerEntity::DeployTerminal(SpReqAnsContext<HealthManagerService_D
 				/** 健康实体过来的调用,1表示不直接重启机器 [Gifur@202275]*/
 				req.reserved1 = 1;
                 Dbg("to install...");
-                tmpResult = pClient->InstallThirdPartyProgram(req, ans, 60000);
+                tmpResult = pClient->InstallThirdPartyProgram(req, ans, 120000);
                 if (tmpResult != 0) {
                     tmpMsg = CSimpleStringA::Format("调用安装请求返回错误:%s", SpStrError((ErrorCodeEnum)tmpResult));
                     Dbg(tmpMsg);

+ 2 - 2
addin/res/ManagerDesktop/js/guide.js

@@ -1541,7 +1541,7 @@ $(function () {
         req.additional = 0;
         req.restartApp = false;
         req.restartPC = false;
-        req.timeout = 65000;
+        req.timeout = 125000;
 
         utilStartSubmitDialog();
         RVC.HealthmanagerEntityCtrl.DeployTerminal(req, function(ret) {
@@ -1595,7 +1595,7 @@ $(function () {
         req.type = 1; //搜狗输入法
         req.reserved1 = 0;
         req.reserved2 = 0;
-        req.timeout = 65000;
+        req.timeout = 125000;
 
         utilStartSubmitDialog();
         RVC.ResourceWatcherEntity.UninstallThirdPartyProgram(req, function(ret) {

+ 51 - 0
addin/res/RunScript/uninstall_tfs_sogouimebs.sh

@@ -0,0 +1,51 @@
+#/bin/bash
+
+CURRENT_PATH="`dirname \"$0\"`"              # relative
+ABS_CURRENT_PATH="`( cd \"$CURRENT_PATH\" && pwd )`"  # absolutized and normalized
+
+UOS_PKG_NAME=*.deb
+UOS_BROSWER="sogouimebs"
+UOS_VERSION=""
+currentInstallVersion=""
+
+check_dream_pkg_installed_or_not() {
+	currentInstallVersion=""
+	if [ "`dpkg -l | grep $UOS_BROSWER`" != "" ]; then
+		currentInstallVersion=$(dpkg -l | grep $UOS_BROSWER | awk '{print $3}')
+		echo "[UOS] Current Installed version: $currentInstallVersion"
+		if [ "$currentInstallVersion" = "$UOS_VERSION" ]; then
+			return 1
+		else
+			return 2
+		fi
+	fi
+	return 0
+}
+
+echo "[UOS] === Install Start === "
+echo "result=-1&msg=install begin"
+
+check_dream_pkg_installed_or_not
+res=$?
+
+if [ $res -eq 0 ]; then
+	echo "[UOS] === expected deb not installed before ===="
+	echo "result=0&msg=expected deb not installed before"
+	exit 0
+else
+	echo "result=-1&msg=pre installed verson: $currentInstallVersion"
+	sudo apt remove $UOS_BROSWER -y
+	sudo apt purge $UOS_BROSWER -y
+	sleep 1s
+	check_dream_pkg_installed_or_not
+	res=$?
+	if [ $res -eq 0 ]; then
+		sudo rm -rf /opt/sogouimebs
+		echo "result=0&msg=uninstall ok"
+		exit 0
+	else
+		echo "result=-2&msg=uninstall failed"
+		exit 1
+	fi
+fi
+