Sep.13

S’amuser avec MSN et .NET : DotMSN

DotMSN est un projet OpenSource proposé par la socièté Xih Solutions disponnible à l’adresse : http://www.xihsolutions.net/dotmsn/.
DotMSN est une assembly .NET écrite en C# qui implémente la quasi-totalité du protocole MSN dans sa version 9.
Vous pourrez grâce à DotMSN:

  • gérer les connexions à MSN, les status, données personnels et images perso
  • gérer la ContactList (ajout, suppression, bloquer, autoriser)
  • gérer de multiples conversations, les emoticones, texte décoré, etc…
  • interface avec Hotmail (connexion, avertissement des nouveaux mail, etc..)
  • gestion des transferts (fichiers, emoticones, images perso des contacts)

Bref, grâce à DotMSN vous pouvez redevelopper entierement votre propre client MSN. La seule chose à la limite qu’il manque, c’est la gestion du Wizz 🙂

Toutes les specs de l’assembly sont disponnible à l’adresse: http://www.xihsolutions.net/dotmsn/api
DotMSN contient 3 espaces de nom :

  • XihSolutions.DotMSN : classes de base pour la connexion/deconnexion, conversation, parametres persos, etc…
  • XihSolutions.DotMSN.Core : c’est le moteur, là où se trouve toute l’implémentation du protocole. Nous n’avons pas besoin d’utiliser les classes qu’il renferme.
  • XihSolutions.DotMSN.DataTransfer : toutes les classes en rapport avec le transfert de fichiers, images, emoticones, etc..

Pour démarrer, commencez par instancier la classe Messenger (dans XihSolutions.DotMSN) puis remplir la propriété Credentials avec comme Account et Password votre compte MSN et le ClientID = « msmsgs@msnmsgr.com » et ClientCode = « Q1P7W2E4J9R8U3S5 » pour enfin lancer la méthode Connect

Vous êtes maintenant connecté au service MSN mais pas encore en ligne. Pour cela abonnez-vous à l’évenement SignedIn dans Nameserver de votre objet MSN (AddHandler msn.Nameserver.SignedIn, AddressOf ….). L’évenement sera appellé dès que votre connexion sera effective. En reponse à l’appel de cet evenement, placez le code :

Le code aura pour but de définir votre pseudo ainsi que votre status.

La proprièté Owner permet donc de definir votre profil, nom, image perso, status, etc… Vous trouverez aussi la propriété ContactList pour la liste de vos contacts. Exemple pour afficher votre ContactList :

Il faudra aussi vous abonnez à l’évenement ConversationCreated de la classe Messenger qui averti qu’une nouvelle conversation est crée. Vous recuperez alors l’objet Conversation qui contient la propriété Switchboard pour pouvoir lire les messages, en envoyer, lancer des invitations de transfert de fichiers, etc… A ce titre, dès qu’une conversation est crée, n’oubliez pas aussi de vous abonnez à l’événement Conversation.Switchboard.TextMessageReceived permettant d’être averti de l’arrivée d’un message.

Enfin pour finir, après la connexion du service MSN, oubliez pas non plus de vous abonnez à l’évenement TransferInvitationReceived de l’objet Messenger permettant d’être averti de l’envoi d’une invitation de transfert. Vous pourrez alors l’accepter en mettant True à la propriété Accept de MSNSLPInvitationEventArgs et démarrer le transfert dans TransferSession.StartDataTransfer(False) (False pour un transfert non direct et True pour direct).
Encore une fois, il faudra vous abonnez à l’évenement TransferFinished de la propriété TransferSession pour être averti de la fin du téléchargement.
Pour enregistrer le fichier transferé en dur dans un fichier :

Voila, vous êtes maintenant paré pour ecrire votre propre client MSN ^_^ Le mieux, pour bien comprendre, est de regarder les specs de l’assembly pour trouver tous les evenements et methodes dont vous aurez besoin. Vous trouverez de toute facon, un client de démo avec les sources fournis en téléchargeant l’assembly DotMSN. Si avez des soucis, n’hesitez pas à me contacter 🙂

Dev,.NET
Share this Story:
  • facebook
  • twitter
  • gplus

Comments(11)

  1. Got
    le 14 septembre 2006 à 23:07

    Hey,
    Alors comme ca à peine rentré de vacances et tu rédiges déjà des articles super sympa.

    Merci pour toutes ces infos super sympa… 🙂

  2. SeBeuH
    le 15 septembre 2006 à 00:32

    Hey Got 🙂 Merci pour ton enfin tes commentaires. Ca fait bien longtemps que je n’ai pas eu de tes nouvelles, depuis le ski et ca me fais bien plaisir que tu me suis sur mon blog 🙂
    Si tu sais m’envoyer ton MSN, ca me ferais plaisir de te parler 🙂
    A bientot jspr ^^

  3. Draek
    le 27 novembre 2006 à 20:58

    Allo seb, mon programme utilise DotMSN, il y a des probleme avec les telechargement des fischier… Est-ce que vous aver utiliser version 2.0 de DotMSN pour transferrer des document??

    Ecris moi ci vous aver d’information… merci!

    draekz at gmail.com

  4. Sebeuh
    le 28 novembre 2006 à 09:51

    Oui j’utilise bien la version 2.0 de l’assembly DotMSN.

    Pour le transfert de fichier, il te suffit de t’abonner à l’évènement TransferInvitationReceived de l’objet Messenger pour recevoir les invitations de transfert. Exemple avant ma methode "Connect" :
    objMessenger.TransferInvitationReceived += new MSNSLPInvitationReceivedEventHandler(objMessenger_TransferInvitationReceived);

    Réponse à l’évènement tu pourra récupérer des infos sur le fichier à transférer comme sa taille (e.FilzSize), son nom (e.FileName), etc….

    Toi, ce qu’il te faut pour démarrer le transfert :
    * Accepter le transfert (e.Accept = true;)
    * Demarrer le transfert en connexion direct ou indirect (indirect: e.TransferSession.StartDataTransfer(false);)
    * T’abonner à l’evenement TransferFinished ( e.TransferSession.TransferFinished);)

    En gros, une fonction de cette forme :
    void objMessenger_TransferInvitationReceived(object sender, MSNSLPInvitationEventArgs e)
    {
    e.Accept = true;
    e.TransferSession.StartDataTransfer(false);
    e.TransferSession.TransferFinished += new EventHandler(TransferSession_TransferFinished);
    }

    Enfin, il faut bien sur faire la fonction en réponse à l’évènement TransferFinished pour enregistrer en dur dans le fichier, le contenu du fichier transféré qui se trouve dans la propriété DataStream de l’objet P2PTransferSession que tu cast en MemoryStream pour l’enregistrer.

    Exemple :
    void TransferSession_TransferFinished(object sender, EventArgs e)
    {
    try
    {
    FileStream stream = new FileStream(file, FileMode.Create, FileAccess.Write, FileShare.Read);
    MemoryStream ms = (MemoryStream)((P2PTransferSession)sender).DataStream;
    stream.Write(ms.GetBuffer(), 0, (int)ms.Position);
    stream.Close();
    }
    catch (Exception ex) { //….. }
    }

    Bon courage à toi 🙂

  5. Draek
    le 28 novembre 2006 à 16:24

    Mon probleme avec ca c’est que on a pas de facon de voir le progres! Je veux avoir tout l’information a propos du transfer… la vitese, lest KB transferer, etc.

    Je pense qu’il faux faire ca nous meme.

    Merci!

  6. sebeuh
    le 29 novembre 2006 à 14:09

    Oui en effet, il faut coder !!

    Tu peux facilement récupérer la taille des données transférées dans ton DataStream pour en déduire le pourcentage d’avancement, la vitesse, etc… Bon courage 😉

    Concernant mon code, il y a plus simple pour éviter d’ attendre la fin du transfert pour enregistrer le fichier transfert en dur dans un fichier par la ligne :

    e.TransferSession.DataStream = new FileStream(<filename>, FileMode.Create, FileAccess.Write);

    .. au niveau de l’invitation du transfert du fichier 🙂

  7. Ckky?
    le 2 décembre 2006 à 12:54

    salut seb,

    As-tu réussi à envoyer des messages avec des emoticones personnalisées à partir de dotmsn ?

    J’ai essayé avec l’exemple fourni dans la package mais sans succès.

    Voici les méthodes que j’ai rajoutées/modifiées dans la classe conversationForm de l’exemple fourni avec dotmsn.

    private ArrayList GetEmoticonsList()
    {
    ArrayList result = new ArrayList();

    string FichierListeEmoticones = ConfigurationSettings.AppSettings.Get("FichierListeEmoticones");
    if (!FichierListeEmoticones.Contains(Application.StartupPath))
    {
    FichierListeEmoticones = (Application.StartupPath + "\\" + FichierListeEmoticones);
    }

    if (File.Exists(FichierListeEmoticones))
    {
    TextReader oTextReader = new StreamReader(FichierListeEmoticones);

    string entreeEmoticone = oTextReader.ReadLine();
    while (entreeEmoticone != null)
    {
    string[] sTab_entreeEmoticone = entreeEmoticone.Split(new char[] { ‘|’ });

    //Emoticon oEmoticon = new Emoticon("kyun", sTab_entreeEmoticone[1], sTab_entreeEmoticone[0]);
    Emoticon oEmoticon = new Emoticon();
    oEmoticon.Creator = Conversation.Messenger.Owner.Name;
    oEmoticon.FileLocation = sTab_entreeEmoticone[1];
    oEmoticon.Shortcut = sTab_entreeEmoticone[0];
    oEmoticon.Image = Image.FromFile(sTab_entreeEmoticone[1]);
    result.Add(oEmoticon);

    entreeEmoticone = oTextReader.ReadLine();
    }

    oTextReader.Close();
    }
    return result;
    }

    private void SendInput()
    {
    // check whether there is input
    if(inputTextBox.Text.Length == 0) return;

    // if there is no switchboard available, request a new switchboard session
    if(Conversation.SwitchboardProcessor.Connected == false)
    {
    Conversation.Messenger.Nameserver.RequestSwitchboard(Conversation.Switchboard, this);
    }

    // note: you can add some code here to catch the event where the remote contact lefts due to being idle too long
    // in that case Conversation.Switchboard.Contacts.Count equals 0.

    TextMessage message = new TextMessage(inputTextBox.Text);

    /* You can optionally change the message’s font, charset, color here.
    * For example:
    * message.Color = Color.Red;
    * message.Decorations = TextDecorations.Bold;
    */

    ArrayList emoticonsList = GetEmoticonsList();
    Conversation.Switchboard.SendEmoticonDefinitions(emoticonsList);

    Conversation.Switchboard.SendTextMessage(message);
    _typingMessageSended = false;
    inputTextBox.Text = "";
    conversationTextBox.Text += "You say: " + message.Text + " ";
    }

    Voilà, si tu peux m’aider ce serait cool.

    Merci 🙂

  8. Ckky?
    le 2 décembre 2006 à 13:02

    Pour résumer, je définis une méthode qui renvoie une ArrayList d’emoticones à partir d’un fichier texte.

    Et je fais appel à la méthode :
    Conversation.Switchboard.SendEmoticonDefinitions(GetEmoticonsList());

    juste avant :
    Conversation.Switchboard.SendTextMessage(message);

    dans la méthode SendInput().

    Je pensais que cela marchait comme ca, mais lorsque j’envoie vers un client wlm, le texte s’affiche normalement, mais le raccourci n’est pas remplacé par l’image.

  9. jc
    le 3 janvier 2007 à 12:25

    Quand je lance leur appli d’exemple (DotMSNClient) j’ai une SocketException :

    "The attempted operation is not supported for the type of object referenced"

    une idee ?

  10. Flo
    le 14 février 2007 à 13:51

    salut merci pour ton bel article

    petite question:

    voici mon abonement AddHandler e.Conversation.Switchboard.TextMessageReceived, AddressOf Me.TextMessageReceived

    et voici mon public sub

    Public Sub TextMessageReceived(ByVal sender As Object, ByVal e As TextMessageEventArgs)
    Debug.WriteLine(e.Sender.Mail & " send " & e.Message.Text)

    Dim messenger As Conversation

    If e.Message.Text.ToLower Like "coucou*" Then
    Dim sMessage As New XihSolutions.DotMSN.TextMessage("Hello")
    messenger.Switchboard.SendTextMessage(sMessage)
    End If
    End Sub

    j’ai une erreur ici messenger.Switchboard.SendTextMessage(sMessage)

    avez vous une idée, merci d’avance

  11. SeBeuH
    le 20 février 2007 à 21:26

    Bonsoir, déjà merci pour vos commentaires et désolé de répondre aussi tard 😉

    Tout d’abord Ckky, j’ai tenté, il y a quelques mois aussi d’envoyer mes propres émoticones mais sans jamais y arriver et pourtant j’ai cherché et tout retourné mais avec le manque de doc c’est pas évidant !
    Il y a pourtant une classe nommée "EmoticonMessage" qui hérite de NetworkMessage mais je n’ai jamais réussit a le mettre en oeuvre 🙁
    Si d’ailleurs des personnes ont des infos, je suis preneur 🙂

    jc > aucune idée ! Si l’exemple fourni avec les sources ne marchent pas c’est qu’en effet il y a un problème qui doit venir d’en dessus !! Google est ton ami 🙂

    Flo > pour toi, l’erreur est normale !! Tu déclare un objet "Conversation" sans l’instancier; il est donc normal que tu ne puisse accéder a ses membres ! Mais même en l’instanciant, cela ne marchera pas, car ta conversation n’est pas rattaché a une conversation !!

    La solution est simple, (et la le reflector est ton ami :)) => le sender passé est de type "SBMessageHandler" qui propose la méthode "SendTextMessage"

    Ce qui revient a écrire :

    Public Sub TextMessageReceived(ByVal sender As Object, ByVal e As TextMessageEventArgs)

    Debug.WriteLine(e.Sender.Mail & " send " & e.Message.Text)

    If e.Message.Text.ToLower().StartWith("coucou") Then

    Dim sMessage As New XihSolutions.DotMSN.TextMessage("Hello")

    CType(sender, SBMessageHandler)
    .SendTextMessage(sMessage)

    End If

    End Sub

    Tu remarqueras aussi que je n’aime pas le Like "coucou*" que j’ai remplacé par .StartWith("coucou") :p

    Bon courage à tous

    Et vive DotMSN 🙂

Leave a comment

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.

Comment