Quoi, tu ne connais pas PB ? Va falloir parcourir tout le forum alors !

Le forum (ô combien francophone) des utilisateurs de Powerbuilder.

Recherche rapide

Annonce

Certaines rubriques, dont des cours, sont uniquement visibles par les membres du forum ^^.
Dans la rubrique Liens & Références, vous avez accès à un sommaire de téléchargement, profitez-en !
Il existe maintenant un nouveau TOPIC "Votre CV en Ligne" accessible uniquement par demande.

#1 02-10-2013 14:43:16

Dadone  
Membre Power Geek
Lieu: Avon (Seine et Marne)
Date d'inscription: 19-02-2007
Messages: 252
Pépites: 985
Banque: 0
Site web

Mail slot C#

Traduction pratiquement instruction par instruction du mail slot PowerBuilder
Enfin presque par ce que C# c'est quant même un peu plus complexe que PB (voir nettement plus complexe).
A vous de juger !

Code: C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using MailSlotCSharp;


namespace MailSlotCSharp
{
    /// <summary>
    ///  Classe qui dépose ou lit de l'information dans un fichier virtuel (mail slot)  par rapport à un chemin 
    ///  Cette classe permet une communication inter-application via des fichiers virtuels.
    /// </summary>
    /// <remarks>
    ///  Au niveau de la génération du projet, la plate forme doit être placée à "Any CPU" ou X64 et doit autoriser du code unsafe.
    /// </remarks>
    /// <example>Principe de fonctionnement
    ///      Un composant P crée deux instances de cette classe : 
    ///        - La première (C1) crée  un mailslot "CSHarp", C1 est capable de lire et d'écrire dans ce dernier.
    ///      - La seconde (C2) peut envoyer un message à un mail slot ouvert par un tiers issu ou non d'un environnement autre que C#
    ///      mais il est  capable d'envoyer un message à un mail slot ouvert par autre composant
    ///    Ainsi P à travers C1 peut envoyer un message dans le mailslot "CSHarp"
    ///        à travers C2 lire un message qui a été envoyé par un autre composant
    ///    Une communication bi directionnelle s'établit donc entre le composant P est un composant extérieur
        /// <seealso lien="http://msdn.microsoft.com/en-us/library/aa365147(VS.85).aspx"></seealso>
    public class MailSlot
    {

        /// <param name="path">Chemin complet où se situe le mailSlot</param>
        /// <param name="messageSize">Optionel, taille maximale des messages, la taille 
        /// par défaut est la taille maximale pour l'API window soit 65536</param>
        /// <param name="timeOutInitial">Temps pour le timeout initial du mail slot</param>
        public MailSlot(string path, int messageSize = MAX_API_MESSAGE_SIZE, int timeOutInitial = 0)
        {
            mailSlotPath    = path;
            messageMaxSize  = messageSize;
            timeOut         = timeOutInitial;
        }

        #region Routines externes (DLL Imports)

        /// <summary>dll de l'API windows qui permet la création d'un canal de communication</summary>
        [DllImport("kernel32.dll")]
        protected static extern IntPtr CreateMailslot(string  lpName,
                                                    int     nMaxMessageSize,
                                                    int     lReadTimeout,
                                                    IntPtr  lpSecurityAttributes);

        /// <summary>ddl de l'API windows qui récupère des informations concerneant un mail slot</summary>
        [DllImport("kernel32.dll")]
        private static extern bool GetMailslotInfo(int hMailslot,
                                               ref int lpMaxMessageSize,
                                               ref int lpNextSize,
                                               ref int lpMessageCount,
                                               ref int lpReadTimeout);
        
        /// <summary>ddl de l'API windows qui crée un fichier virtuel par rapport au canal de communication précédemment ouvert</summary>
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern Int32 CreateFileW(string lpFileName,
                                                uint   dwDesiredAccess,
                                                uint   dwShareMode,
                                                int    lpSecurityAttributes,
                                                int    dwCreationDisposition,
                                                int    dwFlagsAndAttributes,
                                                int    hTemplateFile);

        /// <summary>ddl de l'API windows qui permet de lire un message dans un fichier virtuel</summary>
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool ReadFile(int handle,
                                                byte[]  bytes,
                                                int     numBytesToRead,
                                            out int     numBytesRead,
                                                int     overlapped);
        
        /// <summary>ddl de l'API windows qui permet d'écrire un message dans un fichier virtuel</summary>
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern bool WriteFile(long handle,
                                            byte[]  bytes,
                                            int     numBytesToWrite,
                                        out int     numBytesWritten,
                                            int     overlapped);
        
        /// <summary>ddl de l'API windows qui permet Fermeture du fichier virtuel</summary>
        [DllImport("kernel32.dll", SetLastError = true)]
        private static extern bool CloseHandle(int hObject);
                
        /// <summary>ddl de l'API windows qui permet de modifier le timeout sur le canal de communication précédemment ouvert</summary>
        [DllImport("kernel32.dll", SetLastError = true)]
        private static extern bool SetMailSlotInfo(int hMailslot, int lReadTimeout);
        #endregion

        #region Propriétés constantes

        /// <summary>Taille maximale pour l'API window</summary>
        protected const int MAX_API_MESSAGE_SIZE = 65536;
        
        private const int INVALID_HANDLE_VALUE = -1;

        //File access
        private const uint GENERIC_READ  = 2147483648;         //0x80000000
        private const uint GENERIC_WRITE = 1073741824;         //0x40000000

        //File shares
        private const int FILE_SHARE_READ = 1;

        //Creation types
        private const int CREATE_ALWAYS = 2;
        private const int OPEN_EXISTING = 3;

        //File attributes
        private const int FILE_ATTRIBUTE_NORMAL = 128;
        
        #endregion

        #region Propriétés
        
        /// <summary>Taille des messages du mailslot, affecté lors de l'instanciation</summary>
        protected int messageMaxSize;        

        /// <summary>Chemin complet du mailSlot, affecté lors de l'instanciation</summary>
        protected string mailSlotPath;

        /// <summary>le time Out du mail slot, affecté lors de l'instanciation</summary>
        protected int timeOut;                      


        #endregion

        #region Routines
        /// <summary>
        /// Récupère des informations concernant le mailSlot
        /// </summary>
        /// <param name="slotHandle">Identifiant du mailSlot</param>
        /// <param name="maxmsg">Nombre maximum de messages </param>
        /// <param name="nextmsg">Indicateur du prochain message</param>
        /// <param name="msgcount">Nombre de messages en attente</param>
        /// <param name="timeOut">timeout du mailSlot</param>
        /// <returns> true,  la récupération des informations du mailslot a réussie
        ///           false  impossible de récupérer les informations concernant le malislot
        /// </returns> 
        public bool getMailSlotData(int slotHandle, ref int maxmsg, ref int nextmsg, ref int msgcount, ref int timeOut)
       {
            bool bret;
            bret = GetMailslotInfo(slotHandle, ref maxmsg, ref nextmsg, ref msgcount, ref timeOut);
            return bret;
       } 
          

        /// <summary>
        ///  Création du canal de communication
        /// </summary>
        /// <param name="maxSize">Taille maximale pour le mailslot</param>
        /// <returns> 1, la création a réussie
        ///          -1, la création a échoué
        /// </returns>
        public int CreateMailSlot(uint maxSize) 
        {
            int ret;
            ret = (int)CreateMailslot(mailSlotPath, 0, timeOut, IntPtr.Zero);
            return ret;
        }


        /// <summary>
        ///  Envoie le message au mailslot.
        ///  Le mailslot doit avoit été ouvert
        /// </summary>
        /// <param name="message">Le message a envoyer au mailslot</param>
        /// <returns> 1, l'écriture dans le mail slot a réussie
        ///          -1, une erreur est survenue qui n'a pas permis l'envoi du message
        ///          -2, le fichier associé au mailslot n'existe pas ou n'a pas pu être ouvert
        ///          -3, le message comporte trop de caractères
        ///          -4, le message ne comporte aucun caractère
        /// </returns>
        public int SendMail(string message)
        {
            bool    retWriteFile = false;
            int     retCreateFile;                  // Identifiant du fichier mailSlot, -1 si le mailslot n'a pu être crée
            int     writen;

            try
            {
                if (message.Length == 0) return -4;

                if (message.Length > (long)messageMaxSize) return -3;

                byte[] bMessage = Encoding.Unicode.GetBytes(message);

                retCreateFile = CreateFileW(mailSlotPath, GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);

                switch (retCreateFile)
                {
                    case (INVALID_HANDLE_VALUE):
                        return -2;

                    default:
                        retWriteFile = WriteFile(retCreateFile, bMessage, bMessage.Length, out writen, 0);
                        if (retWriteFile)
                        {
                            CloseHandle(retCreateFile);
                            return 1;
                        }
                        else { return -1; }
                }
            }
            catch (Exception )
            { return -1; }
        }
            
        /// <summary>
        ///  Lit le prochain message depuis le fichier virtuel du mailslot
        /// </summary>
        /// <param name="message">Le message lu dans l afile d'attent du mailslot</param>
        /// <param name="slotMailHandle">La valeur du poiteur qui identifie l'emplacement du mailslot</param>
        /// <returns> 1, le message a été correctement lu
        ///           0, aucun message n'a été lu, file d'attente vide
        ///          -1, une erreur est survenue ne permettant pas de lire le message
        ///          -2, erreur lors de la récupération des données du mailslot
        ///          -3, le mailslot n'a pas été ouvert
        /// </returns> 
        public int ReadMail(ref string message, int slotMailHandle)
        { 
            int     maxMessageSize  = 0;        // Longueur maximum du message
            int     nextMessageSize = 0;        // Longueur du messages prêt à être lu dans le slotMail
            int     messageCount    = 0;        // Nombre de messages dans la file d'attente du mailSlot
            int      timeout         = 0;        // TimeOut défini pour le mailSlot
            int     read            = 0;        // Longueur du message lut
            bool    RetInfoData     = false;

            try
            {
                if (mailSlotExist() == false) return - 3;

                RetInfoData = getMailSlotData(slotMailHandle, ref maxMessageSize, ref nextMessageSize, ref messageCount, ref timeout);

                if (RetInfoData == false)   return -2;
                if (messageCount == 0)      return 0;
                
                var bBuffer = new byte[nextMessageSize];
            
                if (ReadFile(slotMailHandle, bBuffer, nextMessageSize, out read, 0) == false)
                    return -1;
                else
                    message = Encoding.Unicode.GetString(bBuffer);
                    return 1;                                  // le message a été correctement lu 
            }
            catch (Exception )
            { return -1; }
        }                                   

        
        /// <summary>
        /// Test l'existence du mail slot
        /// </summary>
        /// <returns> true,  le mailslot existe
        ///           false, le maislot n'existe pas
        /// </returns> 
        public bool mailSlotExist()
        {
            try
            {
              //   /// <summary>Identifiant du fichier virtuel</summary>
                int fileHandle;

                fileHandle = CreateFileW(mailSlotPath, GENERIC_READ + GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);

                if (fileHandle == INVALID_HANDLE_VALUE)
                {
                    return false;
                }

                CloseHandle(fileHandle);
                return true;
            }
            catch (Exception)
            { return false; }
        } 

        
        /// <summary> Fermeture du  mailslot </summary>
        /// <returns> Code retour de closeHandle(aul_slot) </returns> 
        public bool closeMailSlot(int slothandle)  
        {
            return CloseHandle(slothandle); 
        }

        
        /// <summary>Retourne le nombre de messages en attente dans le mailSlot </summary>
        /// <param name="slotHandle">identifiant du canal de communication</param>
        /// <returns>Nombres de message dans la file d'attente du mailslot
        ///          -1 si une erreur est survenue </returns>  
        public long getMessageNumber(int slotHandle)
        {
            int     msgcount = 0;                // Nombre de messages en attente
            int     maxmsg   = 0;                                 // Paramètres nécessaires à la fonction of_getMailSlotInfo()
            int     nextmsg  = 0;
            int     timeout  = 0;

            try
            {
                if (getMailSlotData(slotHandle, ref maxmsg, ref nextmsg, ref msgcount, ref timeout))
                    return (long)msgcount;
                else
                    return -1;
            }
            catch (Exception)
            { return -1; }
        }       

        
        /// <summary> Modifie le timeout du mailSlot</summary>
        /// <param name="slotHandle">identifiant du canal de communication</param>
        /// <param name="newtimeOut">le nouveau timeout qui va être affecté au mailslot</param>
        /// <returns>retour de la fontion setMailSlotInfo()
        ///          false si une erreur est survenue
        /// </returns>
        public bool setIimeOut(int slotHandle, int newtimeOut)
        {
            try
            {
                timeOut = newtimeOut;
                return SetMailSlotInfo(slotHandle, timeOut);
            }
            catch (Exception)
            { return false; }
        }
        #endregion

    }
}

Dernière modification par Dadone (02-10-2013 20:52:50)

Hors ligne

 

Pied de page des forums

Propulsé par FluxBB 1.2.22