1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
|
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Ipc;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace MonPrgDeTest
{
static class Program
{
//GUID qui ce trouve dans les information de l'assembly (unique, ou probabilité de double très faible)
const String AppGUId = "Local\\db8b778f-e737-4c2a-9675-10e7672xxxxx";
/// <summary>
/// Point d'entrée principal de l'application.
/// </summary>
[STAThread]
static void Main()
{
//permet de faire que l'application ne démare qu'une fois
using (Mutex mutex = new Mutex(false, AppGUId))
{
IpcChannel channel;
if (!mutex.WaitOne(0))
{
//lorsque c'est une 2éme instance, je crée un message
String[] msg = {"Programme déjà en cour d'execution.", "Si vous ne le trouvez pas, vérifiez dans la zone de notification de la barre des taches. Et faite un clique-droite sur son icone."};
// et je me connect au canal qui à été créé lors du lancement de la 1er instance
channel = new IpcChannel();
ChannelServices.RegisterChannel(channel, false);
SingleInstance app = (SingleInstance)Activator.GetObject(typeof(SingleInstance), String.Format("ipc://{0}/RemotingServer", AppGUId));
// et j'envois le message à la 1er instance qui ce chargera de l'affiché
app.Execute(msg);
return;
}
//creation d'un canal pour que la 1ere instance puisse recevoir des arguments
channel = new IpcChannel(AppGUId);
ChannelServices.RegisterChannel(channel, false);
RemotingConfiguration.RegisterWellKnownServiceType(typeof(SingleInstance), "RemotingServer", WellKnownObjectMode.Singleton);
//code par défaut qu'il y a dans le Main
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
// Abonnement à l'évènement SessionEnding
SystemEvents.SessionEnding += new SessionEndingEventHandler(FinDeSession);
Application.Run(new Form1());
//desabonnement à l'évènement SessionEnding (probablement inutile, car si j'en a cette ligne c'est que je quitte cette application)
SystemEvents.SessionEnding -= new SessionEndingEventHandler(FinDeSession); ;
}
}
private delegate void MyDelegate();
/// <summary>
/// Objet utilisé par le serveur et le client (entre la le premier lancement du programe, et les autres)
/// </summary>
private class SingleInstance : MarshalByRefObject
{
public void Execute(String[] args)
{
//affiche un message d'aide
Form MsgForm = new Form{TopMost = true};
MessageBox.Show(MsgForm.Owner, String.Join(Environment.NewLine, args), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information);
//si ma form1 est déjà executé, l'affiche et l'active
if (Application.OpenForms[0].InvokeRequired)
{
Application.OpenForms[0].Invoke(new MyDelegate(Application.OpenForms[0].Show));
Application.OpenForms[0].Invoke(new MyDelegate(Application.OpenForms[0].Activate));
}
}
}
/// <summary>
/// C'est le code qui est censsé etre executé lorsque l'èvent de fin de session est détecté (pas vraiment pu testé cela)
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void FinDeSession(object sender, SessionEndingEventArgs e)
{
// ???? comment je quitte l'application sachant que l'orsque je ferme le formulaire, j'ecrit des information dans le registre
}
}
} |
Partager