refactor(bundler/nsis): replace nsis_process dll usage with nsProcess

`nsis_process` dll is written by us in https://github.com/tauri-apps/nsis-tauri-utils but anti virus tools picks it up as virus. Its code does as much as `nsProcess` but I guss we just don't have enough popularity as `nsProcess` has with anti-virus tools.

closes https://github.com/tauri-apps/nsis-tauri-utils/issues/39
ref: https://github.com/tauri-apps/nsis-tauri-utils/issues/37
This commit is contained in:
amrbashir 2024-09-18 04:50:56 +03:00
parent cbdcee61dc
commit c823ccef6d
No known key found for this signature in database
GPG Key ID: BBD7A47A2003FF33
4 changed files with 246 additions and 32 deletions

View File

@ -33,9 +33,12 @@ const NSIS_URL: &str =
"https://github.com/tauri-apps/binary-releases/releases/download/nsis-3/nsis-3.zip";
#[cfg(target_os = "windows")]
const NSIS_SHA1: &str = "057e83c7d82462ec394af76c87d06733605543d4";
const NSIS_TAURI_UTILS_URL: &str =
"https://github.com/tauri-apps/nsis-tauri-utils/releases/download/nsis_tauri_utils-v0.4.1/nsis_tauri_utils.dll";
const NSIS_TAURI_UTILS_SHA1: &str = "F99A50209A345185A84D34D0E5F66D04C75FF52F";
const NSIS_NS_PROCESS_URL: &str =
"https://github.com/tauri-apps/binary-releases/releases/download/nsis-plugins-v0/nsProcess.dll";
const NSIS_NS_PROCESS_SHA1: &str = "B058E3FCFB7B550041DA16BF10D8837024C38BF6";
const NSIS_SEMVERCOMPARE_URL: &str =
"https://github.com/tauri-apps/nsis-tauri-utils/releases/download/nsis_semvercompare-v0.3.0/nsis_semvercompare.dll";
const NSIS_SEMVERCOMPARE_SHA1: &str = "CD84C1B0D63D217F85E0CC6474FC415C572ADE6D";
#[cfg(target_os = "windows")]
const NSIS_REQUIRED_FILES: &[&str] = &[
@ -43,22 +46,34 @@ const NSIS_REQUIRED_FILES: &[&str] = &[
"Bin/makensis.exe",
"Stubs/lzma-x86-unicode",
"Stubs/lzma_solid-x86-unicode",
"Plugins/x86-unicode/nsis_tauri_utils.dll",
"Include/MUI2.nsh",
"Include/FileFunc.nsh",
"Include/x64.nsh",
"Include/nsDialogs.nsh",
"Include/WinMessages.nsh",
"Plugins/x86-unicode/nsis_semvercompare.dll",
"Plugins/x86-unicode/nsProcess.dll",
];
#[cfg(not(target_os = "windows"))]
const NSIS_REQUIRED_FILES: &[&str] = &["Plugins/x86-unicode/nsis_tauri_utils.dll"];
const NSIS_REQUIRED_FILES: &[&str] = &[
"Plugins/x86-unicode/nsis_semvercompare.dll",
"Plugins/x86-unicode/nsProcess.dll",
];
const NSIS_REQUIRED_FILES_HASH: &[(&str, &str, &str, HashAlgorithm)] = &[(
"Plugins/x86-unicode/nsis_tauri_utils.dll",
NSIS_TAURI_UTILS_URL,
NSIS_TAURI_UTILS_SHA1,
HashAlgorithm::Sha1,
)];
const NSIS_REQUIRED_FILES_HASH: &[(&str, &str, &str, HashAlgorithm)] = &[
(
"Plugins/x86-unicode/nsis_semvercompare.dll",
NSIS_SEMVERCOMPARE_URL,
NSIS_SEMVERCOMPARE_SHA1,
HashAlgorithm::Sha1,
),
(
"Plugins/x86-unicode/nsProcess.dll",
NSIS_NS_PROCESS_URL,
NSIS_NS_PROCESS_SHA1,
HashAlgorithm::Sha1,
),
];
/// Runs all of the commands to build the NSIS installer.
/// Returns a vector of PathBuf that shows where the NSIS installer was created.
@ -111,17 +126,22 @@ fn get_and_extract_nsis(nsis_toolset_path: &Path, _tauri_tools_path: &Path) -> c
fs::rename(_tauri_tools_path.join("nsis-3.08"), nsis_toolset_path)?;
}
let nsis_plugins = nsis_toolset_path.join("Plugins");
let target_folder = nsis_toolset_path.join("Plugins").join("x86-unicode");
fs::create_dir_all(&target_folder)?;
let data = download_and_verify(
NSIS_TAURI_UTILS_URL,
NSIS_TAURI_UTILS_SHA1,
NSIS_SEMVERCOMPARE_URL,
NSIS_SEMVERCOMPARE_SHA1,
HashAlgorithm::Sha1,
)?;
fs::write(target_folder.join("nsis_semvercompare.dll"), data)?;
let target_folder = nsis_plugins.join("x86-unicode");
fs::create_dir_all(&target_folder)?;
fs::write(target_folder.join("nsis_tauri_utils.dll"), data)?;
let data = download_and_verify(
NSIS_NS_PROCESS_URL,
NSIS_NS_PROCESS_SHA1,
HashAlgorithm::Sha1,
)?;
fs::write(target_folder.join("nsProcess.dll"), data)?;
Ok(())
}

View File

@ -0,0 +1,153 @@
; NSIS PROCESS INFO LIBRARY - GetProcessInfo.nsh
; Version 1.1 - Mar 28th, 2011
;
; Description:
; Gets process information.
;
; Usage example:
; ${GetProcessInfo} 0 $0 $1 $2 $3 $4
; DetailPrint "pid=$0 parent_pid=$1 priority=$2 process_name=$3 exe=$4"
;
; History:
; 1.1 - 28/03/2011 - Added uninstall function, include guards, file header. Fixed getting full exe path on pre vista systems. (Sergius)
;
!ifndef GETPROCESSINFO_INCLUDED
!define GETPROCESSINFO_INCLUDED
!define PROCESSINFO.TH32CS_SNAPPROCESS 2
!define PROCESSINFO.INVALID_HANDLE_VALUE -1
!define GetProcessInfo '!insertmacro GetProcessInfo'
;@in pid_in - if 0 - get current process info
;@out pid_out - real process id (may be useful, if pid_in=0)
;@out ppid - parent process id
;@out priority
;@out name - name of process
;@out fullname - fully-qualified path of process
!macro GetProcessInfo pid_in pid_out ppid priority name fullname
Push ${pid_in}
!ifdef __UNINSTALL__
Call un._GetProcessInfo
!else
Call _GetProcessInfo
!endif
;name;pri;ppid;fname;pid;
Pop ${name}
Pop ${priority}
Pop ${ppid}
Pop ${fullname}
Pop ${pid_out}
!macroend
!macro FUNC_GETPROCESSINFO
Exch $R3 ;pid
Push $0
Push $1
Push $2
Push $3
Push $4
Push $5
Push $R0 ;hSnapshot
Push $R1 ;result
Push $R9 ;PROCESSENTRY32;MODULEENTRY32 and so on
Push $R8
;zero registers to waste trash, if error occurred
StrCpy $0 ""
StrCpy $1 ""
StrCpy $2 ""
StrCpy $3 ""
StrCpy $4 ""
StrCpy $5 ""
IntCmp $R3 0 0 skip_pid_detection skip_pid_detection
System::Call 'kernel32::GetCurrentProcess() i.R0'
System::Call "Kernel32::GetProcessId(i R0) i.R3"
skip_pid_detection:
System::Call 'Kernel32::CreateToolhelp32Snapshot(i ${PROCESSINFO.TH32CS_SNAPPROCESS},i R3) i.R0'
IntCmp $R0 ${PROCESSINFO.INVALID_HANDLE_VALUE} end ;someting wrong
;$R9=PROCESSENTRY32
;typedef struct tagPROCESSENTRY32 {
; DWORD dwSize;
; DWORD cntUsage;
; DWORD th32ProcessID;
; ULONG_PTR th32DefaultHeapID;
; DWORD th32ModuleID;
; DWORD cntThreads;
; DWORD th32ParentProcessID;
; LONG pcPriClassBase;
; DWORD dwFlags;
; TCHAR szExeFile[MAX_PATH];
;}PROCESSENTRY32, *PPROCESSENTRY32;
;dwSize=4*9+2*260
System::Alloc 1024
pop $R9
System::Call "*$R9(i 556)"
System::Call 'Kernel32::Process32FirstW(i R0, i $R9) i.R1'
StrCmp $R1 0 end
nnext_iteration:
System::Call "*$R9(i,i,i.R1)" ;get PID
IntCmp $R1 $R3 exitloop
System::Call 'Kernel32::Process32NextW(i R0, i $R9) i.R1'
IntCmp $R1 0 0 nnext_iteration nnext_iteration
exitloop:
;$0 - pid
;$1 - threads
;$2 - ppid
;$3 - priority
;$4 - process name
System::Call "*$R9(i,i,i.r0,i,i,i.r1,i.r2,i.r3,i,&w256.r4)" ; Get next module
;free:
System::Free $R9
System::Call "Kernel32::CloseToolhelp32Snapshot(i R0)"
;===============
;now get full path and commandline
System::Call "Kernel32::OpenProcess(i 1040, i 0, i r0)i .R0"
StrCmp $R0 0 end
IntOp $R8 0 + 256
System::Call "psapi::GetModuleFileNameExW(i R0,i 0,t .r5, *i $R8)i .R1"
end:
Pop $R8
Pop $R9
Pop $R1
Pop $R0
Exch $5
Exch 1
Exch $4
Exch 2
Exch $3
Exch 3
Exch $2
Exch 4
Pop $1
Exch 4
Exch $0
Exch 5
Pop $R3
!macroend ;FUNC_GETPROCESSINFO
Function _GetProcessInfo
!insertmacro FUNC_GETPROCESSINFO
FunctionEnd
Function un._GetProcessInfo
!insertmacro FUNC_GETPROCESSINFO
FunctionEnd
!endif ;GETPROCESSINFO_INCLUDED

View File

@ -19,6 +19,7 @@ ManifestDPIAwareness PerMonitorV2
!include WordFunc.nsh
!include "utils.nsh"
!include "FileAssociation.nsh"
!include "GetProcessInfo.nsh"
!include "Win\COM.nsh"
!include "Win\Propkey.nsh"
!include "StrFunc.nsh"
@ -207,7 +208,7 @@ Function PageReinstall
${EndIf}
${IfThen} $R0 == "" ${|} StrCpy $R4 "$(unknown)" ${|}
nsis_tauri_utils::SemverCompare "${VERSION}" $R0
nsis_semvercompare::SemverCompare "${VERSION}" $R0
Pop $R0
; Reinstalling the same version
${If} $R0 = 0
@ -394,7 +395,8 @@ Var AppStartMenuFolder
!insertmacro MUI_PAGE_FINISH
Function RunMainBinary
nsis_tauri_utils::RunAsUser "$INSTDIR\${MAINBINARYNAME}.exe" ""
; https://mdb-blog.blogspot.com/2013/01/nsis-lunch-program-as-user-from-uac.html
Exec '"$WINDIR\explorer.exe" "$INSTDIR\${MAINBINARYNAME}.exe"'
FunctionEnd
; Uninstaller Pages
@ -725,7 +727,10 @@ Function .onInstSuccess
${GetOptions} $CMDLINE "/R" $R0
${IfNot} ${Errors}
${GetOptions} $CMDLINE "/ARGS" $R0
nsis_tauri_utils::RunAsUser "$INSTDIR\${MAINBINARYNAME}.exe" "$R0"
;https://mdb-blog.blogspot.com/2013/01/nsis-lunch-program-as-user-from-uac.html
CreateShortCut "$TEMP\${MAINBINARYNAME}.lnk" "$INSTDIR\${MAINBINARYNAME}.exe" "$R0"
Exec '"$WINDIR\explorer.exe" "$TEMP\${MAINBINARYNAME}.lnk"'
${EndIf}
${EndIf}
FunctionEnd

View File

@ -18,25 +18,61 @@
${EndIf}
!macroend
!macro FIND_PROCESS_ALL _EXE _RESULT
nsProcess::_FindProcess "${_EXE}"
Pop ${_RESULT}
!macroend
!macro FIND_PROCESS_USER _EXE _RESULT
nsExec::Exec `"$SYSDIR\cmd.exe" /c tasklist /FO csv /FI "USERNAME eq %USERNAME%" /FI "IMAGENAME eq ${_EXE}" | "$SYSDIR\find.exe" "${_EXE}"`
Pop ${_RESULT}
!macroend
!macro FIND_PROCESS _EXE _RESULT
!if "${INSTALLMODE}" == "currentUser"
!insertmacro FIND_PROCESS_USER ${_EXE} ${_RESULT}
!else
${If} $MultiUser.InstallMode == "CurrentUser"
!insertmacro FIND_PROCESS_USER ${_EXE} ${_RESULT}
${Else}
!insertmacro FIND_PROCESS_ALL ${_EXE} ${_RESULT}
${EndIf}
!endif
!macroend
!macro KILL_PROCESS_ALL _EXE _RESULT _CURRENT_PID
nsExec::Exec `taskkill /f /t /im "${_EXE}" /fi "PID ne ${_CURRENT_PID}"`
!macroend
!macro KILL_PROCESS_USER _EXE _RESULT _CURRENT_PID
nsExec::Exec `"$SYSDIR\cmd.exe" /c taskkill /f /t /im "${_EXE}" /fi "PID ne ${_CURRENT_PID}" /fi "USERNAME eq %USERNAME%"`
!macroend
!macro KILL_PROCESS _EXE _RESULT _CURRENT_PID
!if "${INSTALLMODE}" == "currentUser"
!insertmacro KILL_PROCESS_USER ${_EXE} ${_RESULT} ${_CURRENT_PID}
!else
${If} $MultiUser.InstallMode == "CurrentUser"
!insertmacro KILL_PROCESS_USER ${_EXE} ${_RESULT} ${_CURRENT_PID}
${Else}
!insertmacro KILL_PROCESS_ALL ${_EXE} ${_RESULT} ${_CURRENT_PID}
${EndIf}
!endif
!macroend
Var pid
; Checks whether app is running or not and prompts to kill it.
!macro CheckIfAppIsRunning
!if "${INSTALLMODE}" == "currentUser"
nsis_tauri_utils::FindProcessCurrentUser "${MAINBINARYNAME}.exe"
!else
nsis_tauri_utils::FindProcess "${MAINBINARYNAME}.exe"
!endif
!insertmacro FIND_PROCESS "${MAINBINARYNAME}.exe" $R0
Pop $R0
${If} $R0 = 0
IfSilent kill 0
${IfThen} $PassiveMode != 1 ${|} MessageBox MB_OKCANCEL "$(appRunningOkKill)" IDOK kill IDCANCEL cancel ${|}
kill:
!if "${INSTALLMODE}" == "currentUser"
nsis_tauri_utils::KillProcessCurrentUser "${MAINBINARYNAME}.exe"
!else
nsis_tauri_utils::KillProcess "${MAINBINARYNAME}.exe"
!endif
Pop $R0
Sleep 500
${GetProcessInfo} 0 $pid $1 $2 $3 $4
!insertmacro KILL_PROCESS "${MAINBINARYNAME}.exe" $R0 $pid
${If} $R0 = 0
Goto app_check_done
${Else}