How can I check for a running process per user session?

后端 未结 4 1060
抹茶落季
抹茶落季 2021-01-02 13:42

I have a .NET application that I only allow to run a single process at a time of, however that app is used on Citrix boxes from time to time, and as such, can be run by mult

相关标签:
4条回答
  • 2021-01-02 14:00

    As tanascius already say, you can use the Mutex.

    On a server that is running Terminal Services, a named system mutex can have two levels of visibility. If its name begins with the prefix "Global\", the mutex is visible in all terminal server sessions. If its name begins with the prefix "Local\", the mutex is visible only in the terminal server session where it was created.

    Source: msdn, Mutex Class

    0 讨论(0)
  • 2021-01-02 14:05

    Just stating the obvious - although Mutex is usually considered better solution, you can still solve the single-instance-per-session issue without Mutex - just test the SessionId as well.

        private static bool ApplicationIsAlreadyRunning()
        {
            var currentProcess = Process.GetCurrentProcess();
            var processes = Process.GetProcessesByName(currentProcess.ProcessName);
    
            // test if there's another process running in current session.
            var intTotalRunningInCurrentSession = processes.Count(prc => prc.SessionId == currentProcess.SessionId);
    
            return intTotalRunningInCurrentSession > 1;
        }
    

    Source (no Linq)

    0 讨论(0)
  • 2021-01-02 14:11

    EDIT: Improved the answer according to this cw question ...

    You can use a mutex for checking wether the app already runs:

    using( var mutex = new Mutex( false, AppGuid ) )
    {
        try
        {
            try
            {
                if( !mutex.WaitOne( 0, false ) )
                {
                    MessageBox.Show( "Another instance is already running." );
                    return;
                }
            }
            catch( AbandonedMutexException )
            {
                // Log the fact the mutex was abandoned in another process,
                // it will still get aquired
            }
    
            Application.Run(new Form1());
        }
        finally
        {
            mutex.ReleaseMutex();
        }
    }
    

    Important is the AppGuid - you could make it depend on the user.

    Maybe you like to read this article: the misunderstood mutex

    0 讨论(0)
  • 2021-01-02 14:18

    If Form1 launches non-background threads, and that Form1 exits, you've got a problem: the mutex is released but the process is still there. Something along the lines below is better IMHO:

    static class Program {
        private static Mutex mutex;
    
    
    
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main() {
            bool createdNew = true;
            mutex = new Mutex(true, @"Global\Test", out createdNew);
            if (createdNew) {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new Form1());        
            }
            else {
                MessageBox.Show(
                    "Application is already running",
                    "Error",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error
                );
            }
        }
    }
    

    The mutex won't be released as long as the primary application domain is still up. And that will be around as long as the application is running.

    0 讨论(0)
提交回复
热议问题