Find and Close or Terminate: Difference between revisions
No edit summary |
mNo edit summary |
||
Line 2: | Line 2: | ||
== Description == | == Description == | ||
'''Requires:''' [[System]] plug-in. | |||
This macro can find process by it's main window class or title (or title part), 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. | '''Requires:''' [[System plug-in|System]] plug-in. | ||
This macro can find process by it's main window class or title (or title part), 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. Then repeats with all windows of this 'class'. | 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. Then repeats with all windows of this 'class'. | ||
<highlight-nsis> | <highlight-nsis> |
Revision as of 17:03, 19 November 2005
Author: Takhir (talk, contrib) |
Description
Requires: System plug-in.
This macro can find process by it's main window class or title (or title part), 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. Then repeats with all windows of this 'class'.
!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}.$\nClick OK to terminate application." LangString stopMsg ${LANG_ENGLISH} "Stopping ${WND_TITLE} Application" !macro TerminateApp Push $0 ; window handle Push $1 Push $2 ; process handle DetailPrint "$(stopMsg)" loop: FindWindow $0 '${WND_CLASS}' '' 0 $0 IntCmp $0 0 done ; System::Call 'user32.dll::GetWindowText(i r0, t .r1, i 1024) i .r2' ; System::Call 'shell32.dll::StrStr(t r1, t ${WND_TITLE}) i .r2' ; IntCmp $2 0 +1 loop 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_OKCANCEL|MB_ICONEXCLAMATION "$(termMsg)" /SD IDOK IDOK terminate 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' Goto loop done: Pop $2 Pop $1 Pop $0 !macroend Section "Dummy Section" SecDummy !insertmacro TerminateApp SectionEnd
To find window by it's fixed text 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}' 0 $0 FindWindow $0 '${WND_CLASS}' '${WND_TITLE}' 0 $0
To find window by part of it's title (like "WinZip" in the "WinZip - Sample.zip" title) uncomment 3 lines in the code above (GetWindowText, StrStr and IntCmp). To check all top level windows with WND_TITLE in the title (with any window class), remove class parameter in the FindWIndow line
FindWindow $0 '' '' 0 $0