- Checking if my Windows application is running
- 9 Answers 9
- How to check if a process is running via a batch script
- 18 Answers 18
- How can I detect if my app is running on Windows 10
- 7 Answers 7
- Check whether your application is running
- From NSIS Wiki
- Contents
- Using a DDE server
- Using a Win32 Synchronization Object
- Using the name of the process
- Using the name of the process (with Windows’ tasklist command)
- Using a window class or title
- Using a registry entry
Checking if my Windows application is running
How do I check if my C# Windows application is running ?
I know that I can check the process name but the name can be changed if the exe changes.
Is there any way to have a hash key or something to make my application unique?
9 Answers 9
The recommended way is to use a Mutex. You can check out a sample here : http://www.codeproject.com/KB/cs/singleinstance.aspx
In specific the code:
For my WPF application i’ve defined global app id and use semaphore to handle it.
you need a way to say that «i am running» from the app,
1) open a WCF ping service 2) write to registry/file on startup and delete on shutdown 3) create a Mutex
. i prefer the WCF part because you may not clean up file/registry correctly and Mutex seems to have its own issues
Mutex and Semaphore didn’t work in my case (I tried them as suggested, but it didn’t do the trick in the application I developed). The answer abramlimpin provided worked for me, after I made a slight modification.
This is how I got it working finally. First, I created some helper functions:
Then, I added the following to the main method:
If you invoke the application a 3rd, 4th . time, it does not show the warning any more and just exits immediately.
How to check if a process is running via a batch script
How can I check if an application is running from a batch (well cmd) file?
I need to not launch another instance if a program is already running. (I can’t change the app to make it single instance only.)
Also the application could be running as any user.
18 Answers 18
Another possibility I came up with, inspired by using grep, is:
It doesn’t need to save an extra file, so I prefer this method.
Here’s how I’ve worked it out:
The above will open Notepad if it is not already running.
Edit: Note that this won’t find applications hidden from the tasklist. This will include any scheduled tasks running as a different user, as these are automatically hidden.
I like Chaosmaster’s solution! But I looked for a solution which does not start another external program (like find.exe or findstr.exe). So I added the idea from Matt Lacey’s solution, which creates an also avoidable temp file. At the end I could find a fairly simple solution, so I share it.
This is working for me nicely.
The suggestion of npocmaka to use QPROCESS instead of TASKLIST is great but, its answer is so big and complex that I feel obligated to post a quite simplified version of it which, I guess, will solve the problem of most non-advanced users:
The code above was tested in Windows 7, with a user with administrator rigths.
Under Windows you can use Windows Management Instrumentation (WMI) to ensure that no apps with the specified command line is launched, for example:
wmic process where (name=»nmake.exe») get commandline | findstr /i /c:»/f load.mak» /c:»/f build.mak» > NUL && (echo THE BUILD HAS BEEN STARTED ALREADY! > %ALREADY_STARTED% & exit /b 1)
I use PV.exe from http://www.teamcti.com/pview/prcview.htm installed in Program Files\PV with a batch file like this:
TrueY’s answer seemed the most elegant solution, however, I had to do some messing around because I didn’t understand what exactly was going on. Let me clear things up to hopefully save some time for the next person.
TrueY’s modified Answer:
Anyway, I hope that helps. I know sometimes reading batch/command-line can be kind of confusing sometimes if you’re kind of a newbie, like me.
The answer provided by Matt Lacey works for Windows XP. However, in Windows Server 2003 the line
INFO: No tasks are running which match the specified criteria.
which is then read as the process is running.
I don’t have a heap of batch scripting experience, so my soulution is to then search for the process name in the search.log file and pump the results into another file and search that for any output.
I hope this helps someone else.
I like the WMIC and TASKLIST tools but they are not available in home/basic editions of windows.Another way is to use QPROCESS command available on almost every windows machine (for the ones that have terminal services — I think only win XP without SP2 , so practialy every windows machine):
QPROCESS command is not so powerful as TASKLIST and is limited in showing only 12 symbols of process name but should be taken into consideration if TASKLIST is not available.
More simple usage where it uses the name if the process as an argument (the .exe suffix is mandatory in this case where you pass the executable name):
The difference between two ways of QPROCESS usage is that the QPROCESS * will list all processes while QPROCESS some.exe will filter only the processes for the current user.
Using WMI objects through windows script host exe instead of WMIC is also an option.It should on run also on every windows machine (excluding the ones where the WSH is turned off but this is a rare case).Here bat file that lists all processes through WMI classes and can be used instead of QPROCESS in the script above (it is a jscript/bat hybrid and should be saved as .bat ):
And a modification that will check if a process is running:
The two options could be used on machines that have no TASKLIST .
The ultimate technique is using MSHTA . This will run on every windows machine from XP and above and does not depend on windows script host settings. the call of MSHTA could reduce a little bit the performance though (again should be saved as bat):
How can I detect if my app is running on Windows 10
I’m looking for a means to detect if my C# app is running on Windows 10.
I had hoped that Environment.OSVersion would do the trick, but this seems to return a Version of 6.3.9600.0 on Windows 8.1 and Windows 10.
Other solutions such as this don’t seem to distinguish between Windows 8 and Windows 10 either.
Why do I need to do this?
Because I’m using a WinForms WebBrowser control to host an OAuth page that crashes and burns in older IE versions (my app connects to a user’s Nest account. ).
By default, the WebBrowser control emulates IE7. Using a Registry key, you can tell it to emulate the latest version of IE that is installed on the host PC. However, the value that worked up to Windows 8.1 (and pre-releases of Windows 10) does not work in the final version of Windows 10.
7 Answers 7
If you look at registry you will found environment name:
For example my product name is Windows 10 Home :
With this code you get if it Windows 10:
Note: Add using Microsoft.Win32; to your usings.
Answer
Use Environment.OSVersion and add an application manifest file with relevant supportedOS elements uncommented.
e.g. add this under
Reason
I don’t like the answer from @Mitat Koyuncu because is uses the registry unnecessarily and as mentioned in the comments uses unreliable string parsing.
I also don’t like the answer from @sstan because it uses third party code and it needs the application manifest anyway.
Windows 10: VerifyVersionInfo returns false when called by applications that do not have a compatibility manifest for Windows 8.1 or Windows 10 if the lpVersionInfo parameter is set so that it specifies Windows 8.1 or Windows 10, even when the current operating system version is Windows 8.1 or Windows 10. Specifically, VerifyVersionInfo has the following behavior:
• If the application has no manifest, VerifyVersionInfo behaves as if the operation system version is Windows 8 (6.2).
• If the application has a manifest that contains the GUID that corresponds to Windows 8.1, VerifyVersionInfo behaves as if the operation system version is Windows 8.1 (6.3).
• If the application has a manifest that contains the GUID that corresponds to Windows 10, VerifyVersionInfo behaves as if the operation system version is Windows 10 (10.0).
The reason is because VerifyVersionInfo is deprecated in Windows 10.
Check whether your application is running
From NSIS Wiki
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 in your installer script. If you want to check at the very start, use the .onInit (installer) or un.onInit (uninstaller) function. Or you may want to do it later, in a section or a page callback function.
Contents
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. (don’t forget to 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.
Using a Win32 Synchronization 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.
If you can, make sure you choose a unique name for the application mutex, typically generated with the GuidGen tool. ex: «MyApp-<5a60a807-d40c-4554-935a-e570b818df75>«
If you don’t have access to the application source code, you can use tools like ProcessExplorer to find the synchronization objects owned by an application.
An alternative to this approach would be using Named Shared Memory as this allows more flexibility in your main application. In this case the above example would look like this:
Advanced applications may use other Win32 named synchronization objects like an Event or a 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 the 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 risk detecting another unrelated application having the same name as yours.
Additionally you may decide (or offer the user the possibility) to kill the running process forcibly, by using the KillProc plug-in. Note: This can be dangerous as the state of the application and edited files might not be saved correctly.
Note: the FindProcDLL documentation states that as of NSIS 2.46 this plugin no longer works.
Note: there seems to be an alternative working for NSIS 2.46 at NsProcess_plugin
Using the name of the process (with Windows’ tasklist command)
Note: tasklist tool is only present in Windows XP professional or more recent Windows. Ergo, this will not work on Windows XP Home Edition.
An alternative to the FindProc plugin above is to check the output of Windows’ tasklist command to see if it contains the process name. (FindProc didn’t seem to work for the author of this subsection). This could be done with the ExecWait command, but that would flash a command prompt window. Instead, the ExecCmd_plug-in can be used to run the command in a hidden window.
Again, make sure your application executable has an easily identifiable name, or you risk detecting another unrelated application having the same name as yours.
Additionally you may decide (or offer the user the possibility) to kill the running process forcibly, by using the KillProc plug-in. Note: This can be dangerous as the state of the application and edited files might not be saved correctly.
Note: The %SystemRoot%\System prefix is not always necessary, but makes the process robust against users with a modified %PATH%.
Note: this version might give unexpected results when running the setup from an UNC Path as cmd.exe itself doesn’t support it. The result might include a complaining message. To ovverrride this limitation, see this link: http://support.microsoft.com/kb/156276 . DO IT ON YOUR OWN RISK.
Using a window class or title
If your application creates a (main) window with a specific classname or title, you can use it to detect whether the application is running.
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.
You can use the Visual Studio tool Spy++ or a freeware tool like Winlister or WinSpy++ to find the window class of your application.
Once you obtained the window handle with FindWindow , you can also use SendMessage to send WM_CLOSE to close the application. Note that this may not work gracefully with all applications, for example applications with multiple top-level windows.
As FindWindow does not allow wildcards you may try this function to search for partial class name of a window — http://nsis.sourceforge.net/Enhanced_FindWindow_for_variable_window_class_names and this function to match a partial title http://nsis.sourceforge.net/Enhanced_FindWindow_for_variable_window_title_names
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.