useRemoteAppChecker.tsx 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. import { store } from "@/store/store";
  2. import {
  3. execLocal,
  4. fileExists,
  5. nodeCheckRemoteDesktop,
  6. } from "@/utils/nativeMethods";
  7. import { getBlackAppConfig } from "@/utils/common";
  8. import { watch } from "vue";
  9. export function useRemoteAppChecker() {
  10. void getBlackAppConfig();
  11. /** 检测出错则提示;检测通过则将禁用登录按钮的flag置为false */
  12. async function checkRemoteAppTxt() {
  13. if (
  14. !QECSConfig.PREVENT_CHEATING_CONFIG.includes("DISABLE_REMOTE_ASSISTANCE")
  15. )
  16. return;
  17. let applicationNames;
  18. try {
  19. const fs: typeof import("fs") = window.nodeRequire("fs");
  20. try {
  21. applicationNames = fs.readFileSync("remoteApplication.txt", "utf-8");
  22. } catch (error) {
  23. logger({
  24. cnl: ["local", "server"],
  25. key: "checkRemoteAppTxt",
  26. pgu: "AUTO",
  27. dtl: "remoteApplication.txt出错--0",
  28. ejn: JSON.stringify(error),
  29. });
  30. await new Promise((resolve2) => setTimeout(resolve2, 3000));
  31. applicationNames = fs.readFileSync("remoteApplication.txt", "utf-8");
  32. }
  33. } catch (error) {
  34. logger({
  35. cnl: ["local", "server"],
  36. key: "checkRemoteAppTxt",
  37. pgu: "AUTO",
  38. stk: error instanceof Error ? error.message : JSON.stringify(error),
  39. dtl: "读取remoteApplication.txt出错",
  40. ext: { errorType: "e-01", applicationNames },
  41. });
  42. $message.error("请关闭远程控制程序后重试", {
  43. duration: 24 * 60 * 60 * 1000,
  44. });
  45. disableLoginBtnBecauseRemoteApp = true;
  46. return;
  47. }
  48. try {
  49. const { hasSun, hasTodesk } = nodeCheckRemoteDesktop();
  50. if (hasSun) {
  51. applicationNames = (applicationNames ? "" : ",") + "sunloginclient";
  52. }
  53. if (hasTodesk) {
  54. applicationNames = (applicationNames ? "" : ",") + "todesk";
  55. }
  56. } catch (error) {
  57. logger({
  58. cnl: ["local", "server"],
  59. key: "nodeCheckRemoteDesktop",
  60. pgu: "AUTO",
  61. stk: error instanceof Error ? error.message : JSON.stringify(error),
  62. dtl: "读取tasklist出错",
  63. ext: { errorType: "e-01", applicationNames },
  64. });
  65. // 旧版没报错,这里也别报错了
  66. // $message.error("系统检测出错(e-01),请退出程序后重试!", {
  67. // duration: 24 * 60 * 60 * 1000,
  68. // });
  69. // return;
  70. }
  71. if (!applicationNames?.trim()) {
  72. disableLoginBtnBecauseRemoteApp = false;
  73. } else {
  74. let names = applicationNames
  75. .replace("qq", "QQ")
  76. .replace("teamviewer", "TeamViewer")
  77. .replace("lookmypc", "LookMyPC")
  78. .replace("xt", "协通")
  79. .replace("winaw32", "Symantec PCAnywhere")
  80. .replace("pcaquickconnect", "Symantec PCAnywhere")
  81. .replace("sessioncontroller", "Symantec PCAnywhere")
  82. .replace(/sunloginclient/gi, "向日葵")
  83. .replace(/sunloginremote/gi, "向日葵")
  84. .replace(/选择免安装运行,截图识别/gi, "向日葵")
  85. .replace("wemeetapp", "腾讯会议")
  86. .replace("wechat", "微信");
  87. try{
  88. const { nameMap } = await getBlackAppConfig();
  89. for(const key in nameMap){
  90. const value:string = (nameMap )[key]
  91. names.replace(key, value);
  92. }
  93. }catch(err){
  94. console.log('获取nameMap失败:',err)
  95. }
  96. names = [...new Set(names.split(",").map((v) => v.trim()))].join(",");
  97. $message.info(
  98. () => (
  99. <div class="enhanced-error-message">
  100. 在考试期间,请关掉{names}软件,诚信考试。
  101. </div>
  102. ),
  103. {
  104. duration: 24 * 60 * 60 * 1000,
  105. }
  106. );
  107. logger({
  108. cnl: ["local", "server"],
  109. key: "checkRemoteAppTxt",
  110. pgu: "AUTO",
  111. dtl: "在考试期间,请关掉" + names + "软件,诚信考试。",
  112. });
  113. }
  114. }
  115. let disableLoginBtnBecauseRemoteApp = $ref(true);
  116. const QECSConfig = $computed(() => store.QECSConfig);
  117. watch(
  118. () => QECSConfig.PREVENT_CHEATING_CONFIG,
  119. async (val, oldVal) => {
  120. // 由于在刷新时,会重新从sessionStorage里面获取值并设置QECSConfig,
  121. // 同时,还通过网络获取,所以此时的监听会发生两次,两次可能导致 remoteApplication.txt 被删除后读取不到
  122. // 所以此时发现值一样就不要进行后续
  123. if (JSON.stringify(val) === JSON.stringify(oldVal)) return;
  124. if (import.meta.env.DEV) {
  125. disableLoginBtnBecauseRemoteApp = false;
  126. return;
  127. }
  128. if (
  129. !QECSConfig.PREVENT_CHEATING_CONFIG?.includes(
  130. "DISABLE_REMOTE_ASSISTANCE"
  131. )
  132. ) {
  133. disableLoginBtnBecauseRemoteApp = false;
  134. return;
  135. }
  136. let exe = "Project1.exe";
  137. try {
  138. if (fileExists("Project2.exe")) {
  139. const { remoteApp: remoteAppName } = await getBlackAppConfig();
  140. console.log('remoteAppName:',remoteAppName)
  141. exe = `Project2.exe "${remoteAppName}" `;
  142. }
  143. const fs: typeof import("fs") = window.nodeRequire("fs");
  144. fileExists("remoteApplication.txt") &&
  145. fs.unlinkSync("remoteApplication.txt");
  146. } catch (error) {
  147. console.log(error);
  148. logger({
  149. cnl: ["local", "server"],
  150. pgu: "AUTO",
  151. key: "checkRemoteAppTxt",
  152. dtl: "unlink remoteApplication.txt 失败",
  153. possibleError: error,
  154. });
  155. $message.error("请关闭远程控制程序后重试", {
  156. duration: 24 * 60 * 60 * 1000,
  157. });
  158. throw error;
  159. }
  160. await execLocal(exe);
  161. await checkRemoteAppTxt();
  162. },
  163. { immediate: true }
  164. );
  165. return {
  166. disableLoginBtnBecauseRemoteApp: $$(disableLoginBtnBecauseRemoteApp),
  167. checkRemoteAppTxt,
  168. };
  169. }