Find and Close or Terminate: Difference between revisions
From NSIS Wiki
Jump to navigationJump to search
mNo edit summary |
m (Find Close Terminate moved to Find and Close or Terminate) |
||
(One intermediate revision by the same user not shown) | |||
Line 5: | Line 5: | ||
'''Requires:''' [[System plug-in|System]] plug-in. | '''Requires:''' [[System plug-in|System]] plug-in. | ||
This macro can find process by it's main window class or title | This macro can find process by it's main window class or title, try to close it and terminate if process is still alive. Decorated as 'macro' (not function) because this may be usefull both with installer and uninstaller. | ||
Sample below finds window by it's class, sends WM_CLOSE message and waits "timeout" for process exit. If process is still running after this, script asks user's confirmation (optional, comment MessageBox line to skip) and terminates process | Sample below finds window by it's class, sends WM_CLOSE message and waits "timeout" for process exit. If process is still running after this, script asks user's confirmation (optional, comment MessageBox line to skip) and terminates process. | ||
<highlight-nsis> | <highlight-nsis> | ||
!define APP_NAME find_close_terminate | !define APP_NAME find_close_terminate | ||
!define WND_CLASS "Outlook Express Browser Class" | !define WND_CLASS "Outlook Express Browser Class" | ||
Line 21: | Line 22: | ||
LangString termMsg ${LANG_ENGLISH} "Installer cannot stop running ${WND_TITLE}.$\ | LangString termMsg ${LANG_ENGLISH} "Installer cannot stop running ${WND_TITLE}.$\nDo you want to terminate process?" | ||
LangString stopMsg ${LANG_ENGLISH} "Stopping ${WND_TITLE} Application" | LangString stopMsg ${LANG_ENGLISH} "Stopping ${WND_TITLE} Application" | ||
Line 30: | Line 31: | ||
Push $2 ; process handle | Push $2 ; process handle | ||
DetailPrint "$(stopMsg)" | DetailPrint "$(stopMsg)" | ||
FindWindow $0 '${WND_CLASS}' '' | |||
FindWindow $0 '${WND_CLASS}' '' | |||
IntCmp $0 0 done | IntCmp $0 0 done | ||
System::Call 'user32.dll::GetWindowThreadProcessId(i r0, *i .r1) i .r2' | System::Call 'user32.dll::GetWindowThreadProcessId(i r0, *i .r1) i .r2' | ||
System::Call 'kernel32.dll::OpenProcess(i ${SYNC_TERM}, i 0, i r1) i .r2' | System::Call 'kernel32.dll::OpenProcess(i ${SYNC_TERM}, i 0, i r1) i .r2' | ||
Line 41: | Line 38: | ||
System::Call 'kernel32.dll::WaitForSingleObject(i r2, i ${TO_MS}) i .r1' | System::Call 'kernel32.dll::WaitForSingleObject(i r2, i ${TO_MS}) i .r1' | ||
IntCmp $1 0 close | IntCmp $1 0 close | ||
MessageBox | MessageBox MB_YESNOCANCEL|MB_ICONEXCLAMATION "$(termMsg)" /SD IDYES IDYES terminate IDNO close | ||
System::Call 'kernel32.dll::CloseHandle(i r2) i .r1' | System::Call 'kernel32.dll::CloseHandle(i r2) i .r1' | ||
Quit | Quit | ||
Line 48: | Line 45: | ||
close: | close: | ||
System::Call 'kernel32.dll::CloseHandle(i r2) i .r1' | System::Call 'kernel32.dll::CloseHandle(i r2) i .r1' | ||
done: | done: | ||
Pop $2 | Pop $2 | ||
Line 63: | Line 59: | ||
SectionEnd | SectionEnd | ||
</highlight-nsis> | </highlight-nsis> | ||
To find window by it's | To find window by it's title (caption) instead of window class or both by class and title, replace FindWindow line in the macro above with one of the following lines: | ||
<highlight-nsis> | <highlight-nsis> | ||
FindWindow $0 '' '${WND_TITLE}' | FindWindow $0 '' '${WND_TITLE}' | ||
FindWindow $0 '${WND_CLASS}' '${WND_TITLE}' | FindWindow $0 '${WND_CLASS}' '${WND_TITLE}' | ||
</highlight-nsis> | </highlight-nsis> | ||
[[Category:Other Products Handling Functions]] | [[Category:Other Products Handling Functions]] |
Latest revision as of 12:05, 20 November 2005
Author: Takhir (talk, contrib) |
Description
Requires: System plug-in.
This macro can find process by it's main window class or title, try to close it and terminate if process is still alive. Decorated as 'macro' (not function) because this may be usefull both with installer and uninstaller.
Sample below finds window by it's class, sends WM_CLOSE message and waits "timeout" for process exit. If process is still running after this, script asks user's confirmation (optional, comment MessageBox line to skip) and terminates process.
!define APP_NAME find_close_terminate !define WND_CLASS "Outlook Express Browser Class" !define WND_TITLE "Outlook Express" !define TO_MS 2000 !define SYNC_TERM 0x00100001 !include WinMessages.nsh Name "${APP_NAME}" OutFile "${APP_NAME}.exe" LangString termMsg ${LANG_ENGLISH} "Installer cannot stop running ${WND_TITLE}.$\nDo you want to terminate process?" LangString stopMsg ${LANG_ENGLISH} "Stopping ${WND_TITLE} Application" !macro TerminateApp Push $0 ; window handle Push $1 Push $2 ; process handle DetailPrint "$(stopMsg)" FindWindow $0 '${WND_CLASS}' '' IntCmp $0 0 done System::Call 'user32.dll::GetWindowThreadProcessId(i r0, *i .r1) i .r2' System::Call 'kernel32.dll::OpenProcess(i ${SYNC_TERM}, i 0, i r1) i .r2' SendMessage $0 ${WM_CLOSE} 0 0 /TIMEOUT=${TO_MS} System::Call 'kernel32.dll::WaitForSingleObject(i r2, i ${TO_MS}) i .r1' IntCmp $1 0 close MessageBox MB_YESNOCANCEL|MB_ICONEXCLAMATION "$(termMsg)" /SD IDYES IDYES terminate IDNO close System::Call 'kernel32.dll::CloseHandle(i r2) i .r1' Quit terminate: System::Call 'kernel32.dll::TerminateProcess(i r2, i 0) i .r1' close: System::Call 'kernel32.dll::CloseHandle(i r2) i .r1' done: Pop $2 Pop $1 Pop $0 !macroend Section "Dummy Section" SecDummy !insertmacro TerminateApp SectionEnd
To find window by it's title (caption) instead of window class or both by class and title, replace FindWindow line in the macro above with one of the following lines:
FindWindow $0 '' '${WND_TITLE}' FindWindow $0 '${WND_CLASS}' '${WND_TITLE}'