2008-10-08 3 views

cevap

95

Aşağıdakilere benzer bir muteks çözümünü tercih ederim. Zaten yüklü ise bu yol olarak bu benim uygulamada kullanmak budur

using System.Threading; 

[DllImport("user32.dll")] 
[return: MarshalAs(UnmanagedType.Bool)] 
static extern bool SetForegroundWindow(IntPtr hWnd); 

/// <summary> 
/// The main entry point for the application. 
/// </summary> 
[STAThread] 
static void Main() 
{ 
    bool createdNew = true; 
    using (Mutex mutex = new Mutex(true, "MyApplicationName", out createdNew)) 
    { 
     if (createdNew) 
     { 
     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 
     Application.Run(new MainForm()); 
     } 
     else 
     { 
     Process current = Process.GetCurrentProcess(); 
     foreach (Process process in Process.GetProcessesByName(current.ProcessName)) 
     { 
      if (process.Id != current.Id) 
      { 
       SetForegroundWindow(process.MainWindowHandle); 
       break; 
      } 
     } 
     } 
    } 
} 
+6

MainWindowHandle özelliğini bu yolla (yalnızca yeni keşfettiğim gibi) kullanmayla ilgili biraz FYI: "İlişkili işlem bir ana pencereye sahip değilse, * MainWindowHandle değeri sıfırdır *. * Değeri de sıfırdır * için gizlenen süreçler, yani görev çubuğunda görünmeyen işlemler. Bu, bildirim alanında, görev çubuğunun en sağında simgeler olarak görünen işlemler için geçerli olabilir. " –

+0

İyi cevap. SetForegroundWindow'un kabul cevabı üzerinden (bu bağlantıyı izledikten sonra bir sonraki bağlantının ne olduğunu izlerseniz) yayın mesajını kullanan ve pencereyi en üst noktaya zorlayan bir pencere açarım. Bu cevap, yeni çalışan sürecin, çoğu durumda odağı başka bir sürece geçirme haklarına sahip olması gerektiğidir. – eselk

+3

SetForegroundWindow benim için çalışmıyor. Asla işe yaramadı. –

9

uygulaması üzerinde yeniden odaklanır:

static void Main() 
{ 
    bool mutexCreated = false; 
    System.Threading.Mutex mutex = new System.Threading.Mutex(true, @"Local\slimCODE.slimKEYS.exe", out mutexCreated); 

    if(!mutexCreated) 
    { 
    if(MessageBox.Show(
     "slimKEYS is already running. Hotkeys cannot be shared between different instances. Are you sure you wish to run this second instance?", 
     "slimKEYS already running", 
     MessageBoxButtons.YesNo, 
     MessageBoxIcon.Question) != DialogResult.Yes) 
    { 
     mutex.Close(); 
     return; 
    } 
    } 

    // The usual stuff with Application.Run() 

    mutex.Close(); 
} 
22

.net bir programın sadece bir instace çalışan zorlamak için (C#) program.cs dosyasında bu kodu kullanın:

public static Process PriorProcess() 
    // Returns a System.Diagnostics.Process pointing to 
    // a pre-existing process with the same name as the 
    // current one, if any; or null if the current process 
    // is unique. 
    { 
     Process curr = Process.GetCurrentProcess(); 
     Process[] procs = Process.GetProcessesByName(curr.ProcessName); 
     foreach (Process p in procs) 
     { 
      if ((p.Id != curr.Id) && 
       (p.MainModule.FileName == curr.MainModule.FileName)) 
       return p; 
     } 
     return null; 
    } 

ve folowing:

[STAThread] 
    static void Main() 
    { 
     if (PriorProcess() != null) 
     { 

      MessageBox.Show("Another instance of the app is already running."); 
      return; 
     } 
     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 
     Application.Run(new Form()); 
    } 
+4

Bu yanlış bir yoldur. Programınızı iki durumda çalıştırabilirim - biri VS'den ikinci, ikili olarak başlatıldı. – greenoldman

+6

Ok, @goldoldman, ancak ne zamandan beri kullanıcılar/müşteriler uygulamalarınızı "ayıklar" hale getiriyorlar ve daha sonra bunun yanında ikinci bir (ikili) çalıştırmayı seçiyorlar. Bu cevap, bu web sitesinde gördüğüm Mutex tabanlı anologların birçoğuna kıyasla oldukça iyi. –

+3

Bunun yıllar sonra olduğunu biliyorum ama böyle bir şeyi herkesin yaptığı gibi yapması durumunda: Kullanıcı bir yönetici değilse (en azından Win7'de) Process.GetProcessesByName bir istisna atar. –

1

Tek bir uygulama örneğinin bir başka yolu, karma miktarlarını kontrol etmektir. Muteksleri ile karıştırmasını sonra ben bu şekilde çalışma var, (i istediğiniz gibi işe yaramadı):

[DllImport("user32.dll")] 
    [return: MarshalAs(UnmanagedType.Bool)] 
    static extern bool SetForegroundWindow(IntPtr hWnd); 

    public Main() 
    { 
     InitializeComponent(); 

     Process current = Process.GetCurrentProcess(); 
     string currentmd5 = md5hash(current.MainModule.FileName); 
     Process[] processlist = Process.GetProcesses(); 
     foreach (Process process in processlist) 
     { 
      if (process.Id != current.Id) 
      { 
       try 
       { 
        if (currentmd5 == md5hash(process.MainModule.FileName)) 
        { 
         SetForegroundWindow(process.MainWindowHandle); 
         Environment.Exit(0); 
        } 
       } 
       catch (/* your exception */) { /* your exception goes here */ } 
      } 
     } 
    } 

    private string md5hash(string file) 
    { 
     string check; 
     using (FileStream FileCheck = File.OpenRead(file)) 
     { 
      MD5 md5 = new MD5CryptoServiceProvider(); 
      byte[] md5Hash = md5.ComputeHash(FileCheck); 
      check = BitConverter.ToString(md5Hash).Replace("-", "").ToLower(); 
     } 

     return check; 
    } 

o işlem kimliği sadece md5 toplamlarını kontrol eder. Bu uygulamanın bir örneği bulunursa, çalışan uygulamaya odaklanır ve kendi kendiliğinden çıkarsa

.

Yeniden adlandırabilir veya dosyanızla istediğiniz şeyi yapabilirsiniz. md5 hash aynı ise iki kez açılmaz.

Bunu tavsiye eden biri olabilir mi? Cevabını biliyorum, ama belki bir kişi muteks alternatifi arıyor.

İlgili konular