Instance unique + communication de messages (compatible 32 et 64 bit)

Soyez le premier à donner votre avis sur cette source.

Vue 7 377 fois - Téléchargée 487 fois

Description

Cette DLL permet d'avoir une instance unique d'un programme en plus de permettre:
1. La communication de paramètres entre instances (condition: elles doivent être lancées par le même utilisateur)
2. Une fonction pour mettre la fenêtre de l'instance unique au premier plan.

Cette fonction utilise quelques API windows et du code unsafe. Par contre, ce code a été vu pour être fonctionnel nativement autant sur une architecture 32 et 64 bits sans modifications. Elle utilise aussi un fichier projeté en mémoire pour permettre la communication inter-process.

Source / Exemple :


/* Le ZIP contient le projet de la DLL puis un

  • projet d'exemple qui active les fonctionnalités
  • de communication.
  • Étapes pour faire fonctionner l'application:
  • - Créer un SingleInstanceManager global pour
  • l'application dans Main en spécifiant un nom de
  • ressource unique.
  • - Vérifier IsFirstInstance.
*
  • Lors de la création de la form principale (dans le
  • constructeur):
  • - Enregistrez-vous dans l'événement
  • InstanceMessageReceived, qui est nécessaire pour la
  • communication
  • - Appelez SetWindow(this), qui est nécessaire pour la
  • communication et FocusFirstInstance
  • - Surchargez WndProc pour appeler en premier
  • FilterMessage, ce qui permettra le déclenchement
  • des événements et de la communication.
*
  • Pour obtenir la liste des messages en attente:
  • Appelez GetPendingInstanceMessages();
*
  • Vous pouvez utiliser AreMessagesPending pour tester
  • la présence de messages.
*
  • Ci-dessous un exemple partiel d'implémentation:
  • /
using System; using System.Windows.Forms; using Utils; public partial class FrmMain: Form { internal static SingleInstanceManager m_manager; protected override void WndProc(ref Message m) { m_manager.FilterMessage(ref m); base.WndProc(ref m); } public FrmMain() { m_manager.InstanceMessageReceived+=m_manager_IMR; m_manager.SetWindow(this); InitializeComponent(); } void m_manager_IMR(object s,EventArgs e) { foreach(string message in m_manager.GetPendingInstanceMessages()) MessageBox.Show(message); } /* On main le Main dans la classe de form pour l'exemple. */ [STAThread] public static void Main(string[] args) { m_manager = new SingleInstanceManager("MON_NOM_uNiQuE_DE_RESSOURCE_Z94"); if(m_manager.IsFirstInstance) { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new FrmMain()); } else { m_manager.FocusFirstInstance(); foreach(string arg in args) m_manager.SendInstanceMessage(arg); } } }

Conclusion :


J'espère que cette source saura vous combler et qu'elle vous montrera une autre méthode pour rendre une application en instance unique (et en pouvant lui transmettre des paramètres).

Je tiens à mentionner que cette source est inspirée en grande partie du code de Paint.NET. Je l'ai isolée pour les besoins de la cause et j'ai essayé de commenter le mieux possible son fonctionnement.

Pour clarifier, la communication est unidirectionnelle vers l'instance unique.

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

taupe4
Messages postés
94
Date d'inscription
dimanche 16 avril 2006
Statut
Membre
Dernière intervention
17 avril 2008
-
Bah en fait le système de communication doit être paramétré pour être utilisé. Pour les gens qui ne veulent que savoir si ya déjà une instance ouverte, ils n'ont qu'à créer un SingleInstanceManager et, s'ils veulent faire apparaitre leur fenêtre, ils font SetWindow (met le handle dans la zone mappée) et le travail peut se faire. La communication est désactivée tant qu'on ne l'a pas explicitement demandée.
BruNews
Messages postés
21054
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
7 novembre 2014
13 -
Pas que pour le developpeur, pour le CPU aussi...
Mais bon, avec .NET on n'est plus à ça près.
taupe4
Messages postés
94
Date d'inscription
dimanche 16 avril 2006
Statut
Membre
Dernière intervention
17 avril 2008
-
Je tiens à spécifier que ta méthode est effectivement celle utilisée par le programme. Le HWND est transféré dans une région partagée en mémoire. Par contre le "dialogue" est pour envoyer des chaînes de caractères vers l'application. Pour cela envoyer des WM_COPYDATA est plus adapté. Mais cela cause une surcharge pour le développeur .NET, qui doit surcharger WndProc.
taupe4
Messages postés
94
Date d'inscription
dimanche 16 avril 2006
Statut
Membre
Dernière intervention
17 avril 2008
-
@BruNews:
Est-ce que ta source permet le transfert de paramètres comme ceux envoyés par l'éxécutable ? on dirait que non. La première partie est rigoureusement identique à la mienne. Et si c'était juste cela, il existe des mécanismes en .NET qui font cela. Des sources sont d'ores et déjà disponibles sur csharpfr. Mais ma source permet de transférer simplement des chaînes de caractères vers l'instance unique en utilisant WM_COPYDATA. Dans Paint.NET, cette fonctionnalité est utilisée pour envoyer vers la fenêtre les images qu'on ouvre via l'explorateur windows.
BruNews
Messages postés
21054
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
7 novembre 2014
13 -
Surtout pas un pointeur, simplement un nombre de 4 octets qui l'identifie de manière unique dans le système.

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.