2013-07-25 3 views
0

В настоящее время я разрабатываю моноприложение в C#, которое я хотел бы начать только один раз. Я знаю, это может быть достигнуто с помощью мьютекса. Но как я могу принести приложение на фронт, используя моно? Я пытался получать процесс черезЗапуск приложения только один раз (моно)

Process.GetProcessByName("AudioCuesheetEditor") 

, но не может получить доступ к MainWindowHandle.

Как перенести запущенное приложение на передний план?

Спасибо за ответы.

EDIT:

Теперь я был в состоянии получить MainWindowHandle, но это IntPtr. Как перенести этот дескриптор на передний план? Я попытался

Window wRunning = new Window(handle); 
wRunning.Present(); 

, но это дало мне исключение :(

+0

Вы должны изменить заголовок вопроса. – Ma3x

+0

Это приложение winform? – Oscar

+0

Да, приложение winform, основанное на gtk sharp. – Sven

ответ

0

Я был в состоянии исправить это с помощью файловой системы Watcher:.

 FileSystemWatcher fswRunning = new FileSystemWatcher(Path.GetTempPath() + "AudioCuesheetEditor"); 
     fswRunning.Filter = "*.txt"; 
     fswRunning.Changed += delegate(object sender, FileSystemEventArgs e) { 
      log.debug("FileSystemWatcher called Changed"); 
      if (pAudioCuesheetEditor != null) 
      { 
       log.debug("pAudioCuesheetEditor != null"); 
       pAudioCuesheetEditor.getObjMainWindow().Present(); 
      } 
     }; 
     fswRunning.EnableRaisingEvents = true; 
     Boolean bAlreadyRunning = false; 
     Process[] arrPRunning = Process.GetProcesses(); 
     foreach (Process pRunning in arrPRunning) 
     { 
      Boolean bCheckProcessMatch = false; 
      if (Environment.OSVersion.Platform == PlatformID.Unix) 
      { 
       if (pRunning.HasExited == false) 
       { 
        log.debug("pRunning.ProcessName = " + pRunning.ProcessName + " pRunning.MainWindowTitle = " + pRunning.MainWindowTitle); 
        if (pRunning.ProcessName.ToLower().Contains("mono")) 
        { 
         for (int i = 0; i < pRunning.Modules.Count;i++) 
         { 
          if (pRunning.Modules[i].ModuleName.Contains("AudioCuesheetEditor")) 
          { 
           bCheckProcessMatch = true; 
           i = pRunning.Modules.Count; 
          } 
         } 
        } 
       } 
      } 
      else 
      { 
       log.debug("pRunning.ProcessName = " + pRunning.ProcessName); 
       if (pRunning.ProcessName == Process.GetCurrentProcess().ProcessName) 
       { 
        bCheckProcessMatch = true; 
       } 
      } 
      log.debug("bCheckProcessMatch == " + bCheckProcessMatch); 
      if ((pRunning.Id != Process.GetCurrentProcess().Id) && (bCheckProcessMatch == true)) 
      { 
       log.info("Writing to file " + Path.GetTempPath() + "AudioCuesheetEditor" + Path.DirectorySeparatorChar + "message.txt"); 
       File.WriteAllText(Path.GetTempPath() + "AudioCuesheetEditor" + Path.DirectorySeparatorChar + "message.txt","Present"); 
       bAlreadyRunning = true; 
      } 
     } 
     log.debug("bAlreadyRunning = " + bAlreadyRunning); 
     if (bAlreadyRunning == false) 
     { 
       //Start Application 
     } 
0

Используя FSW для этого кажется, очень Hacky.

Я думаю, самое элегантное решение с использованием IPC.

В частности, я будет использовать DBus. Фактически, это то, что используется Banshee, чтобы избежать создания нескольких экземпляров создаваемого объекта. Так что идите и посмотрите наш исходный код, если вам интересно.

+0

Ну, это DBus не только для Linux? – Sven

+0

DBus - это общая система IPC, используемая в Linux, но это не значит, что она не работает с Windows или другими Unix, т. Е. AFAIK вы можете скомпилировать библиотеки DBus с помощью mingw, и, кроме того, если вы используете управляемый DBUS (dbus-sharp), тогда вы даже можете скомпилировать его с .NET, поэтому он должен работать – knocte

+0

Спасибо за отзыв, я попытался использовать NDesk.DBus, но он не работает с окнами.Таким образом, DBus работает только для linux :( – Sven

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