检查应用程序是否已经在当前用户下运行 [英] check if app is running already under current user

查看:177
本文介绍了检查应用程序是否已经在当前用户下运行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在终端服务器情况下,我想确保每个用户仅运行一个应用程序实例.

做到这一点的最佳方法是什么?

这是我当前正在使用的东西,但似乎无法正常工作.我不能100%做到这一点.

int SID = Process.GetCurrentProcess().SessionId;

Process current_process = Process.GetCurrentProcess();
int proc_count = 0;

foreach (Process p in Process.GetProcessesByName(current_process.ProcessName))
{
    proc_count++;
    if (p.SessionId.Equals(SID))
    {
        if (proc_count > 1)
        {
            Application.Current.Shutdown();
            return;
        }
    }
}

更新 为了使我已阅读的评论更清楚,我认为它必须与会话ID无关,因为并非每个用户名每个用户都会跟随一个自然人,并且该用户可以在那里多次登录服务器.

解决方案

通常接受的一种方法是使用命名的互斥锁.通过创建一个命名的互斥锁,您可以确定另一个实例是否已经在运行并关闭新实例.

此代码应为您提供所需的结果.假定所有这些都在可执行文件的主入口点中.

bool createdMutex;
using (var processMutex = new System.Threading.Mutex(false, "Some name that is unique for the executable", out createdMutex)) {

   if (!createdMutex)
     ; // some other instance of the application is already running (or starting up). You may want to bring the other instance to foreground (assuming this is a GUI app)
   else 
   {
      // this is the process to actually run..
      // do application init stuff here
   }
}

请注意,我在此处键入了代码,因此可能存在语法错误,错别字和其他偶然的误导.

根据注释中的请求,以下是选择互斥锁名称的一些说明:

如果要在每个终端服务器会话中将应用程序限制为一个实例,请选择该应用程序唯一的互斥体名称.

如果要将应用程序限制为终端服务器会话中每个用户"的单个实例,请选择该应用程序唯一的互斥体名称,并附加用户的SID. WindowsIdentity.GetCurrent()将为您提供SecurityIdentifier.

如果要将应用程序限制为每个用户一个实例,而不论哪个终端服务器会话,请选择一个互斥量名称,该名称对于包含用户SID的应用程序是唯一的,并在名称前加上"Global \"./p>

如果要将应用程序限制为每个服务器一个实例,请选择该应用程序唯一的互斥体名称,并以"Global \"作为前缀.

重要的是要注意,尽管终端服务器会话与单个用户相关联,但这并不意味着该会话中运行的所有应用程序都与该用户相关联(考虑运行方式"选项).

In a terminal server situation I want to make sure only 1 instance of the application runs for each user.

What is the best way to do this?

Here is what i'm currently using but it seems like it isn't working as intended. I can't be 100% on that.

int SID = Process.GetCurrentProcess().SessionId;

Process current_process = Process.GetCurrentProcess();
int proc_count = 0;

foreach (Process p in Process.GetProcessesByName(current_process.ProcessName))
{
    proc_count++;
    if (p.SessionId.Equals(SID))
    {
        if (proc_count > 1)
        {
            Application.Current.Shutdown();
            return;
        }
    }
}

UPDATE To help clarify by the comments I have read I think it needs to be off the session ID because not all clients will follow one physical person per username and there for the user can be logged into the server multiple times.

解决方案

The generally accepted way to do this is with a named mutex. By creating a named mutex you can determine if another instance is already running and shutdown the new instance.

This code should give you the desired result. All of this is assumed to be in the executable's main entry point.

bool createdMutex;
using (var processMutex = new System.Threading.Mutex(false, "Some name that is unique for the executable", out createdMutex)) {

   if (!createdMutex)
     ; // some other instance of the application is already running (or starting up). You may want to bring the other instance to foreground (assuming this is a GUI app)
   else 
   {
      // this is the process to actually run..
      // do application init stuff here
   }
}

Be warned, I typed the code here, so there may be syntax errors, typos and other accidental misdirection.

As request in the comments, here is some direction on choosing the name of the mutex:

If you want to limit the application to a single instance per terminal server session, then choose a mutex name that is unique to the application.

If you want to limit the application to a single instance per "user" within a terminal server session, choose a mutex name that is unique to the application and append the user's SID. WindowsIdentity.GetCurrent() will provide you with the SecurityIdentifier.

If you want to limit the application to a single instance per user, regardless of which terminal server session, choose a mutex name this is unique to the application with the user's SID included and prefix the name with "Global\".

If you want to limit the application to a single instance per server, choose a mutex name that is unique to the application and prefix with "Global\".

It is important to note that while a terminal server session is associated with a single user, that does not mean that all of the applications running in the session are associated with that user (consider "Run As" options).

这篇关于检查应用程序是否已经在当前用户下运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆