1

Environment: C#, IDE: Visual Studio 2017

I am looking to know if xyz.exe application is running in computer under the current logged-in user.

For Example:

There are 2 users in a computer - User: A (Admin user) & User: B (Non-Admin user)

User A is logged-in the computer and run xyz.exe application and perform session lock operation.

User B is now logged-in in his/her account. (User A is not sign-out, still he/she is logged-in but his/her session is locked)

User A is having xyz.exe application running, but for user B, xyz.exe application is not running.

I want to know if xyz.exe application is running for User B. Is it possible to do that, if yes then How?

I have also updated xyz.exe and it's path where it is running from in the window registry at location: Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run So that once any user do sign-out, after sign-in xyz.exe will start running automatically (It is one of the requirement in my project).

The below code is working:

/// <summary>
/// Declaring Mutex
/// </summary>
private Mutex _mutex = null;

/// <summary>
/// To check if any other instance of xyz.exe is running
/// </summary>
private bool IsSingleInstanceRunning()
{
    // To check if any other instance of xyz.exe is running for currently logged-in user
    _mutex = new Mutex(true, Process.GetCurrentProcess().ProcessName + Environment.UserName, out bool isSingleInstanceRunning);

    // Return true if no instance of xyz.exe is running in task manager for current logged-in user.
    // Return false if multiple instances of xyz.exe is running in task manager for current logged-in user.
    return isSingleInstanceRunning;
}

/// <summary>
/// Entry point of application xyz.exe
/// </summary>
public void ApplicationStartup()
{
    if (!IsSingleInstanceRunning())
    {
        System.Environment.Exit(0);
    }

    // Release Mutex once application is launched
    _mutex.ReleaseMutex();     

    // Keeping mutex object alive for not creating multiple instances for multiple users
    GC.KeepAlive(_mutex);     
    
    // Logic to start application xyz.exe              
}
  • May be you can try this https://stackoverflow.com/questions/6569405/how-to-get-active-process-name-in-c – Dickens A S Sep 18 '20 at 05:52
  • 1
    What's your *real* question? If you want to restrict the number of instances there are far better ways to do it. Someone could just rename the executable and bypass this check. A common trick is to use named mutexes – Panagiotis Kanavos Sep 18 '20 at 05:57
  • 1
    This sounds like a case of [the XY Problem](https://stackoverflow.com/questions/1207105/restrict-multiple-instances-of-an-application). You have a problem, X (how to prevent multiple instances of an application) and assume Y is the solution (list all processes to find if the current one is running multiple times). When that failed you asked about Y, not X. It's quite possible this is an XYZ problem - the root problem may be about licensing. – Panagiotis Kanavos Sep 18 '20 at 06:03
  • @PanagiotisKanavos The real question is - I want to run one instance of xyz.exe application for the current logged-on user. But the above code is allowing me to create one instance of the application for every user. – Rahul Salinskee Sep 18 '20 at 08:19
  • Since two users are already logged on, what does "current user" mean? Both are current as far as they are concerned. Do you want to allow one instance per user, or one instance per machine? – Panagiotis Kanavos Sep 18 '20 at 08:47
  • In any case you could use [GetProcessesByName](https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.process.getprocessesbyname?view=netcore-3.1) to reduce the number or returned processes. It would be a lot cleaner to use named mutexes though. The mutex name could include the user name if you want to force one instance per user. Checking process names is prone to race conditions, mutexes aren't. Or you could use named semaphores, to set a maximum number of instances – Panagiotis Kanavos Sep 18 '20 at 08:52
  • @PanagiotisKanavos Thanks for your suggestion so far. And Yes, I am looking for one instance of xyz.exe per user. I also tried using mutex as you suggested however username is not included in it. Any sample code would be helpful. Thanks – Rahul Salinskee Sep 21 '20 at 04:43
  • *You* provide the name for the mutex. You can use one fixed name which would force only one application to run at a time. Or you can create a name that includes the username, which would force only one instance per user. The duplicate questions show how to do this. In short `Mutex m = new Mutex(true, "myApp", out var createdNew);` is enough. Replace `myApp` with the name you want, eg `$"myApp{WindowsIdentity.GetCurrent().Name}"` and check whether `createdNew` is false. If it's false, the mutex already exists because another instance is running. – Panagiotis Kanavos Sep 21 '20 at 05:52
  • @PanagiotisKanavos I tried this code as you suggested however I am getting an exception as - "Could not find the part of path" `using (Mutex mutex = new Mutex(true, $"xyz{WindowsIdentity.GetCurrent().Name}", out bool isNewInstanceCreated)) { if (!isNewInstanceCreated) { } mutex.Close(); }` – Rahul Salinskee Sep 21 '20 at 08:53
  • Have you tried googling the error ? You'd find [a match immediatelly](https://stackoverflow.com/questions/20714120/could-not-find-a-part-of-the-path-error-while-creating-mutex). Have you inspected the generated name? – Panagiotis Kanavos Sep 21 '20 at 08:55
  • Yes! The exception is happening due to "xyz" in this line of code `using (Mutex mutex = new Mutex(true, $"xyz{WindowsIdentity.GetCurrent().Name}", out bool isNewInstanceCreated))` – Rahul Salinskee Sep 21 '20 at 08:58
  • Okay. I am bale to forced only one instance for each user account. Thanks @PanagiotisKanavos for suggesting ideas. I have replaced the above code with working code. In case, if anyone wants help on this, can try the above code. – Rahul Salinskee Sep 25 '20 at 07:19

0 Answers0