begin process at 2010 02 10 12:00:01
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Astuces

 > INSTANCE UNIQUE + COMMUNICATION DE MESSAGES (COMPATIBLE 32 ET 64 BIT)

INSTANCE UNIQUE + COMMUNICATION DE MESSAGES (COMPATIBLE 32 ET 64 BIT)


 Information sur la source

Note :
9 / 10 - par 1 personne
9,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10
Catégorie :Astuces Source .NET ( DotNet ) Classé sous :instance, unique, communication, inter-process, processus Niveau :Initié Date de création :09/03/2008 Date de mise à jour :11/03/2008 17:43:40 Vu / téléchargé :4 107 / 176

Auteur : taupe4

Ecrire un message privé
Site perso
Commentaire sur cette source (11)
Ajouter un commentaire et/ou une note

 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

  • /* 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);
  • }
  • }
  • }
/* 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.

 Fichier Zip

Les Membres Club peuvent télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip


 Historique

11 mars 2008 17:43:41 :
Ajout d'un code d'exemple dans la boite de code.

 Sources du même auteur

Source avec Zip Source avec une capture Source .NET (Dotnet) TRAITEMENT D'IMAGES EN MASSE
Source avec Zip Source avec une capture Source .NET (Dotnet) COMPOSANT HORLOGE ANALOGIQUE PERSONNALISABLE
Source .NET (Dotnet) LIRE LES BITS D'UN FICHIER ET CRÉER UN FICHIER À PARTIR DE B...

 Sources de la même categorie

Source avec une capture Source .NET (Dotnet) AJOUTER DES BYTES À UN EXECUTABLE par t0fx
Source .NET (Dotnet) COPIER/ COLLER DATAGRID (COPY/PASTE) par jamesbidon
Source avec Zip Source .NET (Dotnet) MECANISME DE SYNCHRONISATION DE THREAD - MONITOR, MUTEX, SEM... par jesusonline
Source .NET (Dotnet) EVENTHANDLERS GÉNÉRIQUES par ricklekebekoi
Source avec Zip Source .NET (Dotnet) TRAITER UN FOREACH EN PARALLÈLE par maitredede

 Sources en rapport avec celle ci

Source avec Zip Source avec une capture Source .NET (Dotnet) LANCER UNE FEUILLE FILLE MDI UNE ET UNE SEULE FOIS par anadeveloppeur
Source avec Zip Source avec une capture Source .NET (Dotnet) [.NET 3.0] WF: EXEMPLE DE COMMUNICATION HÔTE INSTANCE par azra
Source avec Zip Source .NET (Dotnet) OUVRIR DES DOCUMENTS DANS LA MÊME INSTANCE DE L'APPLICATION ... par ShareVB
Source avec Zip Source .NET (Dotnet) LISTER LES HANDLES (FICHIERS, CLÉ DE REGISTRES,...) OUVERTS ... par ShareVB
Source avec Zip Source avec une capture Source .NET (Dotnet) [.NET2] OBTENIR LES PROCESSUS ACTIFS DE TOUS LES COMPTES par Willi

Commentaires et avis

Commentaire de oximoron le 10/03/2008 20:26:54 9/10

Merci mille fois pour cette source ... c'est ce que je cherchais, exactement.
Un peu dommage que se soit aussi hard, du code unsafe et des api windows ... surtout qu'avec vista et cette maudite UAC ca va peut être pas marcher si ? Il n'y a pas moyen de faire ca de manière plus conventionnelle ?

Commentaire de taupe4 le 11/03/2008 17:19:06

Avec vista cela marche parfaitement, y compris avec vista avec UAC activé, il me semble, car cela n'est pas du code affectant des parties sensibles du système. Je n'ai pas rencontré de cas nécéssitant l'UAC avec ce code.

Et, des moyens moins hardcore de transmettre des messages, c'est assez difficile, selon moi. Si tu n'as besoin que d'avoir instance unique les Mutex sont pour ça (il existe des sources ici qui utilisent cela).

Et, quant à moi, j'ai déjà vu du code bien plus horrible et utilisant les API système à fond: un truc qui permet, en .NET, d'utiliser les «common dialogs» Vista.

Commentaire de BruNews le 11/03/2008 19:10:21 administrateur CS

Tu ne te serais pris le crane pour pas grand chose ?

Aucun besoin de dialogue interprocessus ni fichier.
On met 4 octets du hwnd de la fenetre mère dans le fichier d'échange de Windows et basta. Se lit et s'écrit par FileMapping.
Exemple ici:
UNIQUE INSTANCE PROG (WIN32)
http://www.cppfrance.com/code.aspx?ID=25238

Commentaire de oximoron le 11/03/2008 20:08:07

@Taupe4 : Pour avoir essayé sous vista et serveur 2008, ca marche bien UAC activé.
@BruNews  : Moi j'ai une question bête c'est quoi le hwnd ? c'est peu être con mais je ne sais pas ce que c'est. Ta source cpp est transposable en .net ? J'avoue plus trop bien me souvenir du c++, j'en ai pas fait longtemps ;)

Commentaire de BruNews le 11/03/2008 20:15:50 administrateur CS

C'est du C, pas de ++.
HWND c'est le handle de fenêtre, le descripteur unique de chaque fenêtre.

Commentaire de oximoron le 11/03/2008 20:18:24

ok merci, un handle de la fenêtre c'est une sorte de pointeur vers celle ci ? ou je dis une connerie ?

Commentaire de BruNews le 11/03/2008 20:24:12 administrateur CS

Surtout pas un pointeur, simplement un nombre de 4 octets qui l'identifie de manière unique dans le système.

Commentaire de taupe4 le 11/03/2008 23:15:38

@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.

Commentaire de taupe4 le 11/03/2008 23:22:50

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.

Commentaire de BruNews le 12/03/2008 00:47:09 administrateur CS

Pas que pour le developpeur, pour le CPU aussi...
Mais bon, avec .NET on n'est plus à ça près.

Commentaire de taupe4 le 12/03/2008 01:06:47

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.  

 Ajouter un commentaire


Discussions en rapport avec ce code source dans le forum

Communication inter-processus [ par ada3m0n666 ] Bonjour bonjour,j'ai deux processus A et B. Le processus A s'exécute, lance le processus B qui execute quelques instructions puis se met en attente d' Communication entre 2 processus [ par mastar_trek ] Bonjours à tous, j'aurai besoin de créer une interface pour regrouper un ensemble de traitements qui se font pour l'instant par une suite de scripts e Instance de WebService [ par zebobo5 ] Salut tout le monde,mon problème est que j'ai une application winform qui se connecte à un web service, et que je voudrai que mon webservice ne s'inst Objet unique [ par fregolo52 ] Bonjour,Je suis en .NET 1.1Je me suis basé sur le snipper singleton de Nikoui mais ca ne marche pas.Ce que je veux, en gros, c'est un singleton multip [CF] Numero unique d'une carte sim [ par iow4 ] Bonjour,j'ai cherché longtemps sur le site de microsoft et Google mais je n'ai pas trouvé une liste des APIs du compact framework.Mon but serait de tr afficher le programme quand je double-clique sur l'icone [ par cpadmin ] Bonsoir!Voilà en faite j'ai besoin de vos idées et expérience.Ce que j'aimerai faire en faite c'est que quand je démarre mon programme, il regarde si cacher le nom d'un processus dans le gestionnaire des tâches de windows [ par alexSot ] salut chers amis, je lance mon application que j'ai dénommé gestionNet et je voudrais pas qu'un utlisateur averti puisse aller arrêter l'application d communication avec une application java [ par BOULIST ] Boulj'ai une application c#, et je veut communiquer (interagire) avec une application java (console dos) .comment faire?j'ai aussi le code source d Probleme pour ouvrir un fichier par plusieurs processus [ par bossun ] salut,Je cherche à acceder à un meme fichier par 2 processus différents en meme temps... je voudrais que le premier puisse l'ouvir en lecture ecriture CheckListBox avec coche unique [ par RockmanX ] Salut!Je cherche à faire en sorte que l'utilisateur ne puisse pas cocher plus d'un seul élément dans une checkboxlist.J'ai essayé avec les événements


Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Février 2010
LMMJVSD
1234567
891011121314
15161718192021
22232425262728

Consulter la suite du CalendriCode

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 1,388 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales