Jelajahi Sumber

build: Try restart windows service after install (#395)

MystiPanda 1 tahun lalu
induk
melakukan
e54d42576b

+ 33 - 0
scripts/check.mjs

@@ -309,6 +309,38 @@ async function downloadFile(url, path) {
   console.log(`[INFO]: download finished "${url}"`);
 }
 
+// SimpleSC.dll
+const resolvePlugin = async () => {
+  const url =
+    "https://nsis.sourceforge.io/mediawiki/images/e/ef/NSIS_Simple_Service_Plugin_Unicode_1.30.zip";
+
+  const tempDir = path.join(TEMP_DIR, "SimpleSC");
+  const tempZip = path.join(
+    tempDir,
+    "NSIS_Simple_Service_Plugin_Unicode_1.30.zip"
+  );
+  const tempDll = path.join(tempDir, "SimpleSC.dll");
+  const pluginDir = path.join(process.env.APPDATA, "Local/NSIS");
+  const pluginPath = path.join(pluginDir, "SimpleSC.dll");
+  await fs.mkdirp(pluginDir);
+  await fs.mkdirp(tempDir);
+  if (!FORCE && (await fs.pathExists(pluginPath))) return;
+  try {
+    if (!(await fs.pathExists(tempZip))) {
+      await downloadFile(url, tempZip);
+    }
+    const zip = new AdmZip(tempZip);
+    zip.getEntries().forEach((entry) => {
+      console.log(`[DEBUG]: "SimpleSC" entry name`, entry.entryName);
+    });
+    zip.extractAllTo(tempDir, true);
+    await fs.copyFile(tempDll, pluginPath);
+    console.log(`[INFO]: "SimpleSC" unzip finished`);
+  } finally {
+    await fs.remove(tempDir);
+  }
+};
+
 /**
  * main
  */
@@ -365,6 +397,7 @@ const tasks = [
       getLatestReleaseVersion().then(() => resolveSidecar(clashMeta())),
     retry: 5,
   },
+  { name: "plugin", func: resolvePlugin, retry: 5, winOnly: true },
   { name: "service", func: resolveService, retry: 5, winOnly: true },
   { name: "install", func: resolveInstall, retry: 5, winOnly: true },
   { name: "uninstall", func: resolveUninstall, retry: 5, winOnly: true },

+ 1 - 6
src-tauri/src/utils/dirs.rs

@@ -92,14 +92,9 @@ pub fn clash_pid_path() -> Result<PathBuf> {
     Ok(app_home_dir()?.join("clash.pid"))
 }
 
-#[cfg(windows)]
-pub fn service_dir() -> Result<PathBuf> {
-    Ok(app_home_dir()?.join("service"))
-}
-
 #[cfg(windows)]
 pub fn service_path() -> Result<PathBuf> {
-    Ok(service_dir()?.join("clash-verge-service.exe"))
+    Ok(app_resources_dir()?.join("clash-verge-service.exe"))
 }
 
 #[cfg(windows)]

+ 0 - 61
src-tauri/src/utils/init.rs

@@ -240,67 +240,6 @@ pub fn init_resources() -> Result<()> {
     Ok(())
 }
 
-/// initialize service resources
-/// after tauri setup
-#[cfg(target_os = "windows")]
-pub fn init_service() -> Result<()> {
-    let service_dir = dirs::service_dir()?;
-    let res_dir = dirs::app_resources_dir()?;
-
-    if !service_dir.exists() {
-        let _ = fs::create_dir_all(&service_dir);
-    }
-    if !res_dir.exists() {
-        let _ = fs::create_dir_all(&res_dir);
-    }
-
-    let file_list = [
-        "clash-verge-service.exe",
-        "install-service.exe",
-        "uninstall-service.exe",
-    ];
-
-    // copy the resource file
-    // if the source file is newer than the destination file, copy it over
-    for file in file_list.iter() {
-        let src_path = res_dir.join(file);
-        let dest_path = service_dir.join(file);
-
-        let handle_copy = || {
-            match fs::copy(&src_path, &dest_path) {
-                Ok(_) => log::debug!(target: "app", "resources copied '{file}'"),
-                Err(err) => {
-                    log::error!(target: "app", "failed to copy resources '{file}', {err}")
-                }
-            };
-        };
-
-        if src_path.exists() && !dest_path.exists() {
-            handle_copy();
-            continue;
-        }
-
-        let src_modified = fs::metadata(&src_path).and_then(|m| m.modified());
-        let dest_modified = fs::metadata(&dest_path).and_then(|m| m.modified());
-
-        match (src_modified, dest_modified) {
-            (Ok(src_modified), Ok(dest_modified)) => {
-                if src_modified > dest_modified {
-                    handle_copy();
-                } else {
-                    log::debug!(target: "app", "skipping resource copy '{file}'");
-                }
-            }
-            _ => {
-                log::debug!(target: "app", "failed to get modified '{file}'");
-                handle_copy();
-            }
-        };
-    }
-
-    Ok(())
-}
-
 /// initialize url scheme
 #[cfg(target_os = "windows")]
 pub fn init_scheme() -> Result<()> {

+ 0 - 2
src-tauri/src/utils/resolve.rs

@@ -42,8 +42,6 @@ pub fn resolve_setup(app: &mut App) {
     VERSION.get_or_init(|| version.clone());
 
     log_err!(init::init_resources());
-    #[cfg(target_os = "windows")]
-    log_err!(init::init_service());
     log_err!(init::init_scheme());
     log_err!(init::startup_script());
     // 处理随机端口

+ 72 - 3
src-tauri/template/installer.nsi

@@ -15,6 +15,7 @@ Unicode true
 !include WordFunc.nsh
 !include "LogicLib.nsh"
 !include "StrFunc.nsh"
+!addplugindir "$%AppData%\Local\NSIS\"
 ${StrCase}
 ${StrLoc}
 
@@ -423,6 +424,7 @@ FunctionEnd
     nsis_tauri_utils::FindProcess "Clash Verge.exe"
     ${If} $R0 != 0
         ; Kill the process
+        DetailPrint "Kill Clash Verge.exe..."
         !if "${INSTALLMODE}" == "currentUser"
             nsis_tauri_utils::KillProcessCurrentUser "Clash Verge.exe"
         !else
@@ -435,6 +437,7 @@ FunctionEnd
     nsis_tauri_utils::FindProcess "clash-verge-service.exe"
     ${If} $R0 != 0
         ; Kill the process
+        DetailPrint "Kill clash-verge-service.exe..."
         !if "${INSTALLMODE}" == "currentUser"
             nsis_tauri_utils::KillProcessCurrentUser "clash-verge-service.exe"
         !else
@@ -447,6 +450,7 @@ FunctionEnd
     nsis_tauri_utils::FindProcess "clash-meta-alpha.exe"
     ${If} $R0 != 0
         ; Kill the process
+        DetailPrint "Kill clash-meta-alpha.exe..."
         !if "${INSTALLMODE}" == "currentUser"
             nsis_tauri_utils::KillProcessCurrentUser "clash-meta-alpha.exe"
         !else
@@ -458,6 +462,7 @@ FunctionEnd
     nsis_tauri_utils::FindProcess "clash-meta.exe"
     ${If} $R0 != 0
         ; Kill the process
+        DetailPrint "Kill clash-meta.exe..."
         !if "${INSTALLMODE}" == "currentUser"
             nsis_tauri_utils::KillProcessCurrentUser "clash-meta.exe"
         !else
@@ -466,9 +471,70 @@ FunctionEnd
     ${EndIf}
 !macroend
 
-Section
-  !insertmacro CheckAllVergeProcesses
-SectionEnd
+!macro StartVergeService
+  ; Check if the service exists
+  SimpleSC::ExistsService "clash_verge_service"
+  Pop $0  ; 0:service exists;other: service not exists
+  ; Service exists
+  ${If} $0 == 0
+    Push $0
+    ; Check if the service is running
+    SimpleSC::ServiceIsRunning "clash_verge_service"
+    Pop $0 ; returns an errorcode (<>0) otherwise success (0)
+    Pop $1 ; returns 1 (service is running) - returns 0 (service is not running)
+    ${If} $0 == 0
+      Push $0
+      ${If} $1 == 0
+            DetailPrint "Restart Clash Verge Service..."
+            SimpleSC::StartService "clash_verge_service" "" 30
+      ${EndIf}
+    ${ElseIf} $0 != 0
+          Push $0
+          SimpleSC::GetErrorMessage
+          Pop $0
+          MessageBox MB_OK|MB_ICONSTOP "Check Service Status Error ($0)"
+    ${EndIf}
+  ${EndIf}
+!macroend
+
+!macro RemoveVergeService
+  ; Check if the service exists
+  SimpleSC::ExistsService "clash_verge_service"
+  Pop $0  ; 0:service exists;other: service not exists
+  ; Service exists
+  ${If} $0 == 0
+    Push $0
+    ; Check if the service is running
+    SimpleSC::ServiceIsRunning "clash_verge_service"
+    Pop $0 ; returns an errorcode (<>0) otherwise success (0)
+    Pop $1 ; returns 1 (service is running) - returns 0 (service is not running)
+    ${If} $0 == 0
+      Push $0
+      ${If} $1 == 1
+        DetailPrint "Stop Clash Verge Service..."
+        SimpleSC::StopService "clash_verge_service" 1 30
+        Pop $0 ; returns an errorcode (<>0) otherwise success (0)
+        ${If} $0 == 0
+              DetailPrint "Removing Clash Verge Service..."
+              SimpleSC::RemoveService "clash_verge_service"
+        ${ElseIf} $0 != 0
+                  Push $0
+                  SimpleSC::GetErrorMessage
+                  Pop $0
+                  MessageBox MB_OK|MB_ICONSTOP "Clash Verge Service Stop Error ($0)"
+        ${EndIf}
+  ${ElseIf} $1 == 0
+        DetailPrint "Removing Clash Verge Service..."
+        SimpleSC::RemoveService "clash_verge_service"
+  ${EndIf}
+    ${ElseIf} $0 != 0
+          Push $0
+          SimpleSC::GetErrorMessage
+          Pop $0
+          MessageBox MB_OK|MB_ICONSTOP "Check Service Status Error ($0)"
+    ${EndIf}
+  ${EndIf}
+!macroend
 
 Section EarlyChecks
   ; Abort silent installer if downgrades is disabled
@@ -608,6 +674,8 @@ Section Install
     File /a "/oname={{this}}" "{{@key}}"
   {{/each}}
 
+  !insertmacro StartVergeService
+
   ; Create uninstaller
   WriteUninstaller "$INSTDIR\uninstall.exe"
 
@@ -679,6 +747,7 @@ FunctionEnd
 Section Uninstall
   !insertmacro CheckIfAppIsRunning
   !insertmacro CheckAllVergeProcesses
+  !insertmacro RemoveVergeService
   ; Delete the app directory and its content from disk
   ; Copy main executable
   Delete "$INSTDIR\${MAINBINARYNAME}.exe"