2014-08-05 4 views
2

У меня есть приложение Windows Forms с кодом C#, как показано ниже (с таргетингом на .NET framework 4).Как ограничить экземпляры программы C# в Citrix до 1 для пользователя

На моей рабочей станции разработчика этот код работает, чтобы предотвратить запуск нескольких экземпляров программы. Однако 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, но могу узнать.

спасибо.

+0

Первый [быстрый хит google] (http://support.citrix.com/proddocs/topic/xenapp5fp-w2k8/ps-sessions-pub-app-app-lmts-task-v2.html). –

+0

@nobugz: Упрек с благодарностью принят. –

+0

Однако мы не говорим о опубликованном приложении. Наше опубликованное приложение делает системный вызов, который запускает приложение C#, которое затем появляется на экране пользователя. Возможно, мы захотим его опубликовать и запустим его вручную. Или используйте глобальный мьютекс, предложенный Богданом. –

ответ

4

Использование мьютекса Local или Global может быть подходящим в зависимости от того, какое поведение вы используете хотеть.

Использование мьютекса с «Локальным» гарантирует, что для каждого сеанса будет только один экземпляр. Тем не менее, пользователь сможет запускать несколько сеансов на одном сервере (в зависимости от настройки вашей среды 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/форма класса, а не с помощью GC.KeepAlive

+0

Этот ответ называет требование, а объяснение и код выглядят хорошо. Поэтому я отметил это как ответ. К сожалению, из-за рабочей среды Dilbert/CodingHorror я не смогу ее развернуть и протестировать. Только QA и продукция имеют среды Citrix, и у меня больше нет разрешения на выпуск изменений в QA. Такова жизнь. Спасибо! –

2

Использовать глобальный мьютекс. Как ваш код вы можете запускать несколько экземпляров программы в разных пользовательских сеансах ... глобальный мьютекс предотвратит это ...

+0

Возможно, я неправильно понял, но не будет ли это уменьшать количество экземпляров до одной машины (машина, являющаяся сервером Citrix)? Это не соответствовало бы необходимости разрешать один экземпляр для каждого пользователя. –

+0

Да, извините, местный мьютекс - это то, что вам нужно ... просто поставьте «Локальный» перед вашим именем ... – Bogdan

0

Самое простое и лучшее решение для того, чтобы использовать семафор, вот код для этого.

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.

 Смежные вопросы

  • Нет связанных вопросов^_^