如何将Citrix中的C#程序实例限制为每个用户1个

如何将Citrix中的C#程序实例限制为每个用户1个,c#,mutex,multiple-instances,citrix,C#,Mutex,Multiple Instances,Citrix,我有一个Windows窗体应用程序,其C#代码如下所示(针对.NET framework 4) 在我的开发人员工作站上,此代码可以防止我启动程序的多个实例。但是,QA有一个Citrix测试环境,其中每个用户仍然能够启动多个实例 如何防止给定用户在Citrix中运行多个实例 [STAThread] static void Main(string[] args) { bool isFirstInstance; Mutex m = new Mutex(true, "[App name

我有一个Windows窗体应用程序,其C#代码如下所示(针对.NET framework 4)

在我的开发人员工作站上,此代码可以防止我启动程序的多个实例。但是,QA有一个Citrix测试环境,其中每个用户仍然能够启动多个实例

如何防止给定用户在Citrix中运行多个实例

[STAThread]
static void Main(string[] args)
{
    bool isFirstInstance;
    Mutex m = new Mutex(true, "[App name goes here] mutex", out isFirstInstance);

    if (isFirstInstance)
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run();

        // Prevent the just-in-time (JIT) compiler from optimizing away our Mutex.
        // See: http://www.ai.uga.edu/mc/SingleInstance.html
        GC.KeepAlive(m);
    }
}
出于技术原因,我们希望限制实例的数量。该程序使用自托管WCF与同一用户运行的另一个进程进行通信。我们每个用户只需要这个程序的一个实例

我不知道关于Citrix环境的任何细节,但可以查询


谢谢。

使用全局互斥。您的代码可以在不同的用户会话中启动程序的多个实例。。。全局互斥将防止…

根据您想要的行为,使用本地或全局作用域互斥是合适的

使用带有“Local\”的互斥体将确保每个会话只运行一个实例。但是,您的用户仍然可以在同一台服务器上启动多个会话(取决于Citrix环境的配置),因此您的应用程序的多个实例可以在不同的会话中运行

如果您想成为100%的用户,每个服务器上只有一个实例,那么您需要使用全局互斥。但是,您需要确保使用特定于用户的状态命名互斥对象,例如

string globalMutexName = string.Format(
    CultureInfo.InvariantCulture,
    "Global\\AppName~{0}~{1}~some-unique-guid",
    Environment.UserDomainName,
    Environment.UserName);

_machineLocalAppInstanceMutex = new System.Threading.Mutex(true, globalMutexName, out mutexIsNew);

if (!mutexIsNew)
{
    Shutdown();
}

此外,我还将使互斥对象成为类的成员,通常是您的主应用程序/表单类,而不是使用GC.KeepAlive

最简单和最好的解决方案是使用互斥对象,下面是代码

static void Main(string[] args)
{
        String mutexName = "MyApplication" + 
        System.Security.Principal.WindowsIdentity.GetCurrent().User.AccountDomainSid;

        Boolean createdNew;

        Mutex mutex = new Mutex(true, mutexName, out createdNew);

        if (!createdNew)
        {
            //If createdNew is false that means an instance of application is already running for this   
            // user.
            //So in this case stop the application from executing.
            return;
        }
        Console.ReadKey();
}

您可以在这里找到详细的解释。

第一个分数。@nobugz:感谢您的斥责。不过,我们这里不是在讨论已发布的应用程序。我们发布的应用程序进行系统调用,启动C#应用程序,然后出现在用户屏幕上。我们可能希望发布它,并让用户手动启动它。或者像Bogdan建议的那样使用全局互斥。也许我误解了,但这会不会将实例减少到每台机器一个(这台机器就是Citrix服务器)?这不能满足每个用户只允许一个实例的需要。是的,对不起,本地互斥是你需要的。。。只需在你的名字前面加上“Local\”。这个答案符合要求,解释和代码看起来都不错。因此,我已将其标记为答案。不幸的是,由于Dilbert/Codinghoror工作环境,我无法部署和测试它。只有QA和生产部门有Citrix环境,我不再有授权发布对QA的更改。这就是生活。非常感谢。