【问题标题】:How to limit instances of a C# program in Citrix to 1-per-user如何将 Citrix 中的 C# 程序实例限制为每个用户 1 个
【发布时间】:2014-08-05 21:53:02
【问题描述】:

我有一个带有 C# 代码的 Windows 窗体应用程序,如下所示(针对 .NET 框架 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环境的任何细节,但可以询问。

谢谢。

【问题讨论】:

  • 第一个quicky google hit 得分。
  • @nobugz:感激地接受谴责。
  • 我们在这里讨论的不是已发布的应用程序。我们发布的应用程序进行系统调用,启动 C# 应用程序,然后出现在用户的屏幕上。我们可能想要发布它,并让用户手动启动它。或者像 Bogdan 建议的那样使用全局互斥锁。

标签: c# mutex multiple-instances citrix


【解决方案1】:

根据您想要的行为,使用本地或全局范围的互斥锁可能是合适的。

将互斥锁与“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();
}

另外我会让互斥锁成为一个类的成员,通常是你的主 App/Form 类,而不是使用 GC.KeepAlive

【讨论】:

  • 这个答案符合要求,解释和代码看起来都不错。因此,我将其标记为答案。不幸的是——由于 Dilbert/CodingHorror 工作环境——我将无法部署和测试它。只有 QA 和生产具有 Citrix 环境,我不再有权将更改发布给 QA。这就是人生。谢谢!
【解决方案2】:

使用全局互斥锁。您的代码的方式是您可以在不同的用户会话中启动程序的多个实例......全局互斥锁将阻止......

【讨论】:

  • 也许我误解了,但这不会将实例减少到每台机器一个(机器是 Citrix 服务器)吗?这不能满足每个用户允许一个实例的需要。
  • 是的,抱歉,您需要的是本地互斥锁...只需在您的姓名前加上“Local\”...
【解决方案3】:

最简单和最好的解决方案是使用互斥体,这里是它的代码。

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();
}

你可以在这个link找到详细的解释。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-27
    • 1970-01-01
    • 2019-01-20
    • 1970-01-01
    • 2015-06-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多