Check whether your application is running: Difference between revisions

From NSIS Wiki
Jump to navigationJump to search
No edit summary
Line 1: Line 1:
{{PageAuthor|saabz_500}}
{{PageAuthor|saabz_500}}


== Description ==
There are many methods to detect whether your application is running or not.
This example detects if the application you are uninstalling is running at the start of the uninstallation process.
<br>The easiest way to find the "WindowClassOfYourApplication" and "WindowTitleOfYourApplication" is to use Microsoft Spy++. Spy++ is a tool that comes with Visual Studio. You can also use the freeware tool SysTree++ to find the WindowClass.


== The Example Script ==
It is much better to implement a method that involve some kind of cooperation from your application so that you are sure that you will detect your application specifically.
However many of these methods also work without specific cooperation from the application.
 
Choose your method below, and place the adequate code inside your installer
<highlight-nsis>
Function .onInit
    ...
FunctionEnd
</highlight-nsis>
or your uninstaller:
<highlight-nsis>
Function un.onInit
    ...
FunctionEnd
</highlight-nsis>
 
== using a DDE server ==
If the application implements a DDE server, your (un)installer can use the [[nsisDDE plug-in]] to contact the DDE server to query its state, bring the application to the foreground or ask the application to exit.
 
If your application is written in MFC, it is very easy to add a DDE server in it.. (use GuidGen tool to generate a unique service identifier specific to your application)
 
Many applications already implement such a DDE server (typically used by Explorer to open/print documents). You can search for "ddeexec" keys under HKEY_CLASSES_ROOT to find the name of applications' DDE server.
 
Examples:
<highlight-nsis>
nsisDDE::Execute "MyApp-{5A60A807-D40C-4554-935A-E570B818DF75}" "[Quit]"
Pop $0
IntCmp $0 0 notRunning
    Sleep 2000 ; give 2 seconds for the application to finish exiting
notRunning:
</highlight-nsis>
<highlight-nsis>
<highlight-nsis>
/* Replace the values of the two defines below to your application's window class and window title, respectivelly. */
nsisDDE::Execute "MyApp-{5A60A807-D40C-4554-935A-E570B818DF75}" "[SetForeground]"
!define WNDCLASS "WindowClassOfYourApplication"
Pop $0
!define WNDTITLE "WindowTitleOfYourApplication"
IntCmp $0 0 notRunning
    MessageBox MB_OK|MB_ICONEXCLAMATION "MyApp is running (foreground window). Please close it first" /SD IDOK
    Abort
notRunning:
</highlight-nsis>


Function un.onInit
== using a Win32 Synchronisation Object ==
  FindWindow $0 "${WNDCLASS}" "${WNDTITLE}"
Many applications typically create a named mutex to prevent multiple instance of the application.
  StrCmp $0 0 continueInstall
Your (un)installer could call the Win32 API "OpenMutex" to detect if this named mutex is active.
     MessageBox MB_ICONSTOP|MB_OK "The application you are trying to remove is running. Close it and try again."
 
Example:
<highlight-nsis>
System::Call 'kernel32::OpenMutex(i 0x100000, b 0, t "MyAppMutex") i .R0'
IntCmp $R0 0 notRunning
    System::Call 'kernel32::CloseHandle(i $R0)'
    MessageBox MB_OK|MB_ICONEXCLAMATION "MyApp is running. Please close it first" /SD IDOK
    Abort
notRunning:
</highlight-nsis>
 
Advanced applications may use other Win32 named synchronization objects like an Event or Pipe to send a signal or a command to the application.
 
== using the name of the process ==
You can detect if your application is running by using [[FindProcDLL plug-in]] to check if a process having the name of your application executable is running.
 
Make sure your application executable has an easily identifiable name, or you may detect another unrelated application having the same name as yours.
 
Example:
<highlight-nsis>
FindProcDLL::FindProc "MyApp.exe"
IntCmp $R0 1 0 notRunning
    MessageBox MB_OK|MB_ICONEXCLAMATION "MyApp is running. Please close it first" /SD IDOK
    Abort
notRunning:
</highlight-nsis>
 
== using a window class ==
If your application creates a (main) window with a specific classname or title, you can use it to detect whether the application is running.
You can use Visual Studio tool Spy++ or freeware tool SysTree++ to find the window class of your application.
 
Unless you're sure of the application behaviour, be aware that many applications have dynamically generated window classname (different each time), and localized window title depending on the user language.
 
Examples:
<highlight-nsis>
FindWindow $0 "MyAppWindowClass"
StrCmp $0 0 notRunning
    MessageBox MB_OK|MB_ICONEXCLAMATION "MyApp is running. Please close it first" /SD IDOK
    Abort
</highlight-nsis>
or
<highlight-nsis>
FindWindow $0 "" "MyApp Window Title"
StrCmp $0 0 notRunning
     MessageBox MB_OK|MB_ICONEXCLAMATION "MyApp is running. Please close it first" /SD IDOK
    Abort
</highlight-nsis>
 
== using a registry entry ==
Your application could, for example, write 1 on startup in a registry entry, and write 0 when the application is closed.
You can then test this registry in your (un)installer.
 
However this solution is not clean because the registry would not be reset to 0 if your application crashes or is forcibly killed.
 
Example:
<highlight-nsis>
ReadRegDWORD $R0 HKLM "SOFTWARE\MyCompany\MyApp" "IsRunning"
IntCmp $R0 0 notRunning
    MessageBox MB_OK|MB_ICONEXCLAMATION "MyApp is running. Please close it first" /SD IDOK
     Abort
     Abort
  continueInstall:
notRunning:
FunctionEnd
</highlight-nsis>
</highlight-nsis>


For any queries mail me at :saabz_500@yahoo.co.uk
 


[[Category:Code Examples]]
[[Category:Code Examples]]

Revision as of 12:47, 30 June 2010

Author: saabz_500 (talk, contrib)


There are many methods to detect whether your application is running or not.

It is much better to implement a method that involve some kind of cooperation from your application so that you are sure that you will detect your application specifically. However many of these methods also work without specific cooperation from the application.

Choose your method below, and place the adequate code inside your installer

Function .onInit
    ...
FunctionEnd

or your uninstaller:

Function un.onInit
    ...
FunctionEnd

using a DDE server

If the application implements a DDE server, your (un)installer can use the nsisDDE plug-in to contact the DDE server to query its state, bring the application to the foreground or ask the application to exit.

If your application is written in MFC, it is very easy to add a DDE server in it.. (use GuidGen tool to generate a unique service identifier specific to your application)

Many applications already implement such a DDE server (typically used by Explorer to open/print documents). You can search for "ddeexec" keys under HKEY_CLASSES_ROOT to find the name of applications' DDE server.

Examples:

nsisDDE::Execute "MyApp-{5A60A807-D40C-4554-935A-E570B818DF75}" "[Quit]"
Pop $0
IntCmp $0 0 notRunning
    Sleep 2000 ; give 2 seconds for the application to finish exiting
notRunning:
nsisDDE::Execute "MyApp-{5A60A807-D40C-4554-935A-E570B818DF75}" "[SetForeground]"
Pop $0
IntCmp $0 0 notRunning
    MessageBox MB_OK|MB_ICONEXCLAMATION "MyApp is running (foreground window). Please close it first" /SD IDOK
    Abort
notRunning:

using a Win32 Synchronisation Object

Many applications typically create a named mutex to prevent multiple instance of the application. Your (un)installer could call the Win32 API "OpenMutex" to detect if this named mutex is active.

Example:

System::Call 'kernel32::OpenMutex(i 0x100000, b 0, t "MyAppMutex") i .R0'
IntCmp $R0 0 notRunning
    System::Call 'kernel32::CloseHandle(i $R0)'
    MessageBox MB_OK|MB_ICONEXCLAMATION "MyApp is running. Please close it first" /SD IDOK
    Abort
notRunning:

Advanced applications may use other Win32 named synchronization objects like an Event or Pipe to send a signal or a command to the application.

using the name of the process

You can detect if your application is running by using FindProcDLL plug-in to check if a process having the name of your application executable is running.

Make sure your application executable has an easily identifiable name, or you may detect another unrelated application having the same name as yours.

Example:

FindProcDLL::FindProc "MyApp.exe"
IntCmp $R0 1 0 notRunning
    MessageBox MB_OK|MB_ICONEXCLAMATION "MyApp is running. Please close it first" /SD IDOK
    Abort
notRunning:

using a window class

If your application creates a (main) window with a specific classname or title, you can use it to detect whether the application is running. You can use Visual Studio tool Spy++ or freeware tool SysTree++ to find the window class of your application.

Unless you're sure of the application behaviour, be aware that many applications have dynamically generated window classname (different each time), and localized window title depending on the user language.

Examples:

FindWindow $0 "MyAppWindowClass"
StrCmp $0 0 notRunning
    MessageBox MB_OK|MB_ICONEXCLAMATION "MyApp is running. Please close it first" /SD IDOK
    Abort

or

FindWindow $0 "" "MyApp Window Title"
StrCmp $0 0 notRunning
    MessageBox MB_OK|MB_ICONEXCLAMATION "MyApp is running. Please close it first" /SD IDOK
    Abort

using a registry entry

Your application could, for example, write 1 on startup in a registry entry, and write 0 when the application is closed. You can then test this registry in your (un)installer.

However this solution is not clean because the registry would not be reset to 0 if your application crashes or is forcibly killed.

Example:

ReadRegDWORD $R0 HKLM "SOFTWARE\MyCompany\MyApp" "IsRunning"
IntCmp $R0 0 notRunning
    MessageBox MB_OK|MB_ICONEXCLAMATION "MyApp is running. Please close it first" /SD IDOK
    Abort
notRunning: