Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Práce s Mutex aneb má aplikace bude spuštěná jen jednou

V minulé lekci, Paralelní třída a PLINQ v C# .NET, jsme se naučili paralelní třídu.

Pokud je nežádoucí, aby se vaše aplikace spouštěla více krát, pak čtěte dál.

Mutual exclusion (zkráceně Mutex) zabraňuje více násobnému použití částí, které si nepřejme sdílet. Vytváří se s nějakým klíčovým slůvkem, nejčastěji při použití pro náš úkon s názvem aplikace. Pokud již proces s tímto mutexem běží, pak se to po vytvoření instance Mutexu dozvíme.

Používá se také například i v instalátorech - nelze přepsat soubory, když jsou používány,

Přesuňme se do souboru Program.cs, kde vytvoříme novou instanci Mutexu:

bool createdNew;
Mutex appMutex = new Mutex(true, Application.ProductName, out createdNew);

Při vytvoření instance Mutexu je jeho výstupem také proměnná typu boolean ve které je uložena informace o tom, zda již mutex se stejným jménem existuje nebo se právě teď vytvořil.

Nyní nám již nic nebrání v tom si přidat jednoduchou podmínku.

if (createdNew)
    Application.Run(new Form1());
else
    MessageBox.Show("Tato aplikace může být spuštěna pouze jednou!");

Ovšem toto, je uživatelsky nepřívětivé a lepší by bylo, kdyby se při dalším kliku na soubor aplikace zobrazila v popředí.

A proto si vytvoříme třídu SingleInstance

public static class SingleInstance
{
    public const int HWND_BROADCAST = 0xffff;
    public static int WM_SHOWME = RegisterWindowMessage("MOJE_APLIKACE_ZOBRAZ_OKNO");
    [DllImport("user32")]
    public static extern bool PostMessage(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam);
    [DllImport("user32")]
    public static extern int RegisterWindowMessage(string message);

    public static void ShowForm()
    {
        SingleInstance.PostMessage(
            (IntPtr)SingleInstance.HWND_BROADCAST,
            SingleInstance.WM_SHOWME,
            IntPtr.Zero,
            IntPtr.Zero);
    }
}

Bude nás zajímat proměnná WM_SHOME, která obsahuje klíč, pomocí kterého se v programu pak vykoná daná metoda. Doporučuji tedy klidně se rozepsat a napsat něco unikátního. Můžete takto i ovládat aplikaci. Pokud si vytvoříte více takových můžete je pak obdobným způsobem volat.

Metoda ShowForm vyšle signál v podobě zadné RegisterWindow­Message a ten aplikace zpracuje v daném Formu nejčastěji v tom hlavním:

protected override void WndProc(ref System.Windows.Forms.Message m)
{
    if (m.Msg == SingleInstance.WM_SHOWME)
    {
        this.Show();
        WindowState = FormWindowState.Normal;
        this.Activate();
    }

    base.WndProc(ref m);
}

Přepíšeme metodu WndProc a přidáme do ní podmínku, pokud je příkazem náš příkaz proveď zobrazení okna. Teď již určitě chápete jak primitivní je udělat si aplikaci, ze které můžete ovládat jinou aplikaci. Je to sice k ničemu, ale pobaví to :)

Do Program.cs nyní jen v else zavoláme SingleInstance­.ShowForm();

Paralelní programování a vícevláknové aplikace v C# .NET

Poznámky:
Stalo se mi, že výše uvedený způsob nefungoval. Řešení může být následující: Zavolání metody appMutex.ReleaseMutex() před spuštěním programu. Ovšem i toto mě zklamalo. Přidal jsem tedy ještě podmínku Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName).Length == 1). Tedy podívám se, kolik procesů ze stejným názvem je spuštěno. Pokud jen jeden (ten současný), pokračuji, jinak zobrazím okno aplikace.


 

Stáhnout

Stažením následujícího souboru souhlasíš s licenčními podmínkami

Staženo 354x (40.3 kB)
Aplikace je včetně zdrojových kódů v jazyce C#

 

Předchozí článek
Paralelní třída a PLINQ v C# .NET
Všechny články v sekci
Paralelní programování a vícevláknové aplikace v C# .NET
Článek pro vás napsal David Jančík
Avatar
Uživatelské hodnocení:
4 hlasů
Autor je vášnivý programátor. Nezná slovo "nelze", nebojí se zkoušet nepoznané a pronikat do nových technologií.
Aktivity