diff --git a/scripts/check.mjs b/scripts/check.mjs index f4f14b4c..87ba5b88 100644 --- a/scripts/check.mjs +++ b/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 }, diff --git a/src-tauri/src/utils/dirs.rs b/src-tauri/src/utils/dirs.rs index 43b406dc..8930e15d 100644 --- a/src-tauri/src/utils/dirs.rs +++ b/src-tauri/src/utils/dirs.rs @@ -92,14 +92,9 @@ pub fn clash_pid_path() -> Result { Ok(app_home_dir()?.join("clash.pid")) } -#[cfg(windows)] -pub fn service_dir() -> Result { - Ok(app_home_dir()?.join("service")) -} - #[cfg(windows)] pub fn service_path() -> Result { - Ok(service_dir()?.join("clash-verge-service.exe")) + Ok(app_resources_dir()?.join("clash-verge-service.exe")) } #[cfg(windows)] diff --git a/src-tauri/src/utils/init.rs b/src-tauri/src/utils/init.rs index 5ce1488f..0e7245ee 100644 --- a/src-tauri/src/utils/init.rs +++ b/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<()> { diff --git a/src-tauri/src/utils/resolve.rs b/src-tauri/src/utils/resolve.rs index bc21e004..8b7864a9 100644 --- a/src-tauri/src/utils/resolve.rs +++ b/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()); // 处理随机端口 diff --git a/src-tauri/template/installer.nsi b/src-tauri/template/installer.nsi index 1ffd23da..bcafefb2 100644 --- a/src-tauri/template/installer.nsi +++ b/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"