none
Meilleur article 01.02.2011 - 01.03.2011 RRS feed

  • Discussion générale

  • Bonjour tout le monde !

    En programmant on est parfois amené à devoir enregistrer des données sur l’ordinateur cible, et encore mieux, on aimerait pouvoir ouvrir directement ses fichiers avec notre programme. J’ai donc découvert un moyen de créer notre propre extension que je vais vous expliquer.
    Pour lire le contenu d’un fichier portant cette extension, on a le choix entre permettre l’ouverture/lecture à partir de plusieurs programmes comme le Bloc-Notes, ou encore pouvoir le lire uniquement avec notre propre programme. Le but étant de créer notre propre extension, une extension propriétaire en quelque sorte, on choisira la deuxième option.

    La création, qui n’a rien de compliqué, va être décrite en plusieurs étapes.

    Le but ici sera de demander un nom et un prénom à l’utilisateur, qu’on enregistrera dans un fichier  ".test1" . Cette extension étant notre extension personnalisée. Le programme saura donc ouvrir cette extension et afficher Bienvenue à l’utilisateur ayant enregistré son nom et prénom. Bien sûr on aurait pu faire cela autrement ou plus facilement, mais le but et simplement de montrer le fonctionnement.

    Étape 1 :

    La première chose à faire (en partant du fait qu’on sache déjà ce qu’on va enregistrer) est de choisir comment on va écrire et lire les données.
    On pourrait simplement écrire ligne par ligne les instructions, ou encore se définir un standard.
    Ici on va plutôt utiliser le standard XML, de plus qu’on a déjà pleins de fonctions prévues à cet effet dans le Framework qui nous simplifieront la vie. Je ne fais pas de cours de XML, rien n’est compliqué ici ;)

    Je pars ici à partir d’un formulaire qui contient :
    - 4 Labels : un "Bienvenue <NomUtilisateur>", un "Nom :", un "Prenom :" et un "Chemin :"
    - 3 TextBox : txtNom, txtPrenom, txtChemin
    - 1 Bouton

    Voilà l'image représentant le formulaire : http://img19.imageshack.us/img19/5/frmej.png

    Importez également les espaces de noms suivants :

    Imports System.Xml
    Imports System.IO

     

    Attention, notre programme va écrire dans le registre, il nous faudra donc lancer le programme en tant qu'administrateur. Pour cela on va cliquer sur Projet=> Propriété de <nom de votre assembly> pour ouvrir les propriétés de notre projet. On clique ensuite sur "Afficher les paramètres Windows" et le fichier app.manifest s'ouvre.

    On modifiera la ligne :

    <requestedExecutionLevel level="asInvoker" uiAccess="false" />

    en :

    <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />

    On va ensuite écrire une sous-procédure pour enregistrer le nom et prénom en XML :

     Sub EnregistrerPref()
    
        Dim donneesXML As String = "<?xml version=""1.0"" encoding=""utf-8"" ?>" 'ligne nécessaire pour adhérer au standard
        donneesXML = String.Concat(donneesXML, vbNewLine, "<Enregistrement>") 'notre balise principale
        donneesXML = String.Concat(donneesXML, vbNewLine, vbTab, "<Prenom>" & txtPrenom.Text & "</Prenom>")
        donneesXML = String.Concat(donneesXML, vbNewLine, vbTab, "<Nom>" & txtNom.Text & "</Nom>")
        donneesXML = String.Concat(donneesXML, vbNewLine, "</Enregistrement>")
    
        'on enregistre sous notre propre extension (et ici, sur le bureau)
        Using sr As New StreamWriter(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) & "\monExt.test1")
          sr.Write(donneesXML) 'on écrit les données
        End Using
    
      End Sub

     

    Rien de très difficile, on concatène la chaîne au fur et à mesure avec un nouveau champ et sa mise en forme via vbNewLine et vbTab. On enregistre ensuite sur le bureau grâce au StreamWriter. Pour l’instant rien n’est crypté et donc en ouvrant monExt.test1 avec le bloc-notes on verra le contenu.
    Double-cliquez sur le bouton sauvegarder et entrez simplement : EnregistrerPref()

    Étape 2 :

    À présent on va associer l’extension "test1" à notre programme.
    Pour cela on écrit cette procédure :

     Sub AssocierExtension()
    
        Dim extension As String = ".test1" 'notre extension
    
        Dim nomSansPoint As String = extension.Substring(1, extension.Length - 1) 'on aura uniquement test1 sans le point
        Dim cheminFinalProgramme = "<CHEMIN DU PROGRAMME>" 'à remplacer par le chemin "final" du programme une fois installé
    
        My.Computer.Registry.ClassesRoot.CreateSubKey(extension).SetValue("", nomSansPoint, Microsoft.Win32.RegistryValueKind.String)
    
        My.Computer.Registry.ClassesRoot.CreateSubKey(nomSansPoint & "\shell\open\command").SetValue _
          ("", "<CHEMIN DU PROGRAMME>" & " ""%l"" ", Microsoft.Win32.RegistryValueKind.String)
    
        'ajout de l'icone
        My.Computer.Registry.ClassesRoot.OpenSubKey(nomSansPoint, True).CreateSubKey("DefaultIcon").SetValue("", "<CHEMIN DU PROGRAMME>,0")
    
      End Sub

     

    Notez le  "%1" qui est simplement un argument de notre programme et qui nous permettra d’obtenir le chemin du fichier lancé afin de l’utiliser avec notre programme. On aura quelque chose du genre : MonProgrammeInitial.exe monExt.test. Le zéro après la virgule signifie l’icône par défaut de votre programme (il faut déjà qu’il en contienne) et est le chemin absolu du programme sur l’ordinateur cible. Pour ajouter une icône à notre programme, on va à nouveau dans Projet => Propriétés de <nom de l'assembly> puis choisir notre icône en cliquant sur "Parcourir" à la place de (Icône par défaut).

    Étape 3 :

    Maintenant, notre programme sait ouvrir un fichier lorsqu’il est passé en argument, mais bien entendu, on aura pas à noter MonProgrammeInitial.exe monExt.test1 tout le temps pour chaque fichier (même si ça fonctionne aussi). En effet on va simplement double cliquer sur notre .test1 comme tout autre programme.

    Mais pour cela il nous faut écrire quelque chose qui va intercepter le fichier passé en argument (double-cliqué) et lire son contenu. On va donc créer une sous-procédure pour lire et interpréter le code XML qu’on a écrit auparavant et une autre pour souhaiter la bienvenue à l’utilisateur :

     Public Sub LireXML(ByVal XML As String)
    
        Dim document As New XmlDocument
        document.LoadXml(XML)
        'on récupère le nom et prénom de l'utilisateur
        Dim prenom As XmlNodeList = document.GetElementsByTagName("Prenom")
        Dim nom As XmlNodeList = document.GetElementsByTagName("Nom")
      
        SouhaiterBienvenue(prenom(0).InnerText, nom(0).InnerText)
    
      End Sub
    
      Public Sub SouhaiterBienvenue(ByVal prenom As String, ByVal nom As String)
    
        Dim utilis As String = String.Format("{0} {1}", nom, prenom)
        Label1.Text = "Bienvenue " & utilis 'on souhaite la bienvenue à l'utilisateur ayant enregistré le fichier test1
    
      End Sub

     

    Enfin, on écrit donc dans la procédure Form1_Load (double-cliquez sur le formulaire pour l’afficher) :

     Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    
        Try
          If My.Computer.Registry.ClassesRoot.OpenSubKey(".test1") Is Nothing Then
    
            'si l'extension n'est pas encore associée, on l'associe.
            associerExtension()
    
          End If
    
        Catch ex As Exception
          MsgBox("Erreur d'association de l'extension.")
        End Try
    
        'on obtient les arguments, à savoir le nom du fichier avec lequel le prog s'est ouvert
        For Each argument As String In Environment.GetCommandLineArgs()
          If argument.Contains("test1") Then 'si il contient notre extension 'test1
            txtChemin.Text = txtChemin.Text & argument 'on affiche le chemin du fichier test1
    
            LireXML(My.Computer.FileSystem.ReadAllText(argument)) 'on lit le fichier
          End If
        Next
    
      End Sub

    La txtChemin contiendra le chemin du fichier lancé.
    Notez qu’on lit le code XML à la fin de la procédure. Ce qui va donc souhaiter la bienvenue à l’utilisateur.

    À partir de maintenant on a tout, il reste éventuellement à crypter le tout:

    Cryptage du XML :

    Pour cela on va importer deux nouveaux espaces de noms :

    Imports System.Text
    Imports System.Security.Cryptography

    Suivis de nos fonctions de cryptage/décryptage :

    Public Function Cryptage(ByVal donnees As String) As String
    
        Dim sha1 As New SHA1Managed
        Convert.ToBase64String(sha1.ComputeHash(Encoding.ASCII.GetBytes(donnees)))
        Dim donneeCryptees() As Byte = ASCIIEncoding.ASCII.GetBytes(donnees)
        Dim cryptageEnString As String = Convert.ToBase64String(donneeCryptees)
        Return cryptageEnString
    
      End Function
      Public Function Decryptage(ByVal donnees As String) As String
    
        Dim donneeDecryptees() As Byte = Convert.FromBase64String(donnees)
        Dim decryptageEnString As String = ASCIIEncoding.ASCII.GetString(donneeDecryptees)
        Return decryptageEnString
    
      End Function

    Il reste à présent à crypter/décrypter nos données en changeant la procédure Form1_Load et EnregistrerPref :

     Sub EnregistrerPref()
    
        Dim donneesXML As String = "<?xml version=""1.0"" encoding=""utf-8"" ?>" 'ligne nécessaire pour adhérer au standard
        donneesXML = String.Concat(donneesXML, vbNewLine, "<Enregistrement>") 'notre balise principale
        donneesXML = String.Concat(donneesXML, vbNewLine, vbTab, "<Prenom>" & txtPrenom.Text & "</Prenom>")
        donneesXML = String.Concat(donneesXML, vbNewLine, vbTab, "<Nom>" & txtNom.Text & "</Nom>")
        donneesXML = String.Concat(donneesXML, vbNewLine, "</Enregistrement>")
    
        'on enregistre sous notre propre extension (et ici, sur le bureau)
        Using sr As New StreamWriter(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) & "\monExt.test1")
          sr.Write(Cryptage(donneesXML)) 'ligne changée
        End Using
    
      End Sub
    
     Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    
        Try
          If My.Computer.Registry.ClassesRoot.OpenSubKey(".test1") Is Nothing Then
    
            'si l'extension n'est pas encore associée, on l'associe.
            associerExtension()
    
          End If
    
        Catch ex As Exception
          MsgBox("Erreur d'association de l'extension.")
        End Try
    
        'on obtient les arguments, à savoir le nom du fichier avec lequel le prog s'est ouvert
        For Each argument As String In Environment.GetCommandLineArgs()
          If argument.Contains("test1") Then 'si il contient notre extension 'test1
            txtChemin.Text = txtChemin.Text & argument 'on affiche le chemin du fichier test1
    
            LireXML(Decryptage(My.Computer.FileSystem.ReadAllText(argument))) 'ligne changée
          End If
        Next
    
      End Sub

    Finalement, en mettant respectivement  » Nom  » et  » Prenom  » dans les textbox, en sauvegardant et en ouvrant monExt.test1, on obtient directement ceci :

    http://img33.imageshack.us/img33/6945/final2f.png

     


    N'hésitez pas à poser des questions si un problème subsiste ou quelque chose n'est pas clair. Dans l'autre cas, veuillez indiquer que le problème est résolu. Cordialement.
    • Fractionné Alex Petrescu mardi 1 mars 2011 15:35 meilleur article
    dimanche 13 février 2011 20:43

Toutes les réponses

  • Bonjour Michel,

    Tout à fait pour le format propriétaire, si l'extension n'est pas déclarée aucune application ne saura l'ouvrir, mais il vaut peut être mieux faire un binaire car quand ça ne s'ouvre pas, la première chose qu'on fait (et c'est peut être même proposé automatiquement par défaut), ben on ouvre le fichier en texte avec le bloc-notes :o)

    Cordialement.

     



    Joseph Attila PUSZTAY
    EhJoe       Logiciels       Romans       Ecrire
    lundi 14 février 2011 11:20
  • Bonjour,

    J'ai bien cette idée d'associé un programme a une extension particulière :)
    il est sur que c'est  juste une démo (un exemple) qui est en soit pas mal, qui demandera a chaque personne une adaptation.
    perso si j'utilise votre code j’utiliserais Linq To XML pour l'ecriture du XML, et un moyen de cryptage plus adapté !

     

    Merci

     

     


    Cordialement, Troxsa
    lundi 14 février 2011 12:22
    Auteur de réponse
  • Ah oui en effet les exemples Linq To XML ont l'air d'être faciles à mettre en place :)

    Sinon petite précision (j'ai peur d'éditer car tout mon code se déforme..) l'icône sera associée avec l'extension, ici "test1", au redémarrage du système (en tout cas sous Windows 7 64 bits, et sûrement sur les autres OS).

    Autre précision : La fonction de cryptage n'est pas sûre à 100% dans le sens ou il suffit de recopier le code du fichier "test1" pour le décrypter via la fonction de décryptage donnée. Mais bon en pratique on privilègiera une routine de cryptage avec mot de passe par exemple (comme rc4), si bien sûr on souhaite protéger notre application ou comme le dit EhJoe, sauvegarder sous forme binaire.

     


    N'hésitez pas à poser des questions si un problème subsiste ou quelque chose n'est pas clair. Dans l'autre cas, veuillez indiquer que le problème est résolu. Cordialement.
    lundi 14 février 2011 15:52
  • Oui pour l’édition c'est un problème du forum je pense, une fois édité toute la mises en page est complément désorganiser (FireFox ?)

    ce qui pourrais être sympa pour ce qui concerne la publication d'un article serait de mettre le projet (sous format zip) a dispo de tout les intéressés, qu'en pensez vous ?


    Cordialement,
    Xavier
    Alias Troxsa My M@iL
    mardi 15 février 2011 15:33
    Auteur de réponse
  • Bonjour,

     

    La plateforme du forum cause parfois des problèmes, surtout s’il s’agit d’un post contenant beaucoup de texte.

     

    Je suis d’accord avec la proposition de Xavier d’attacher le projet en format zip. Vous pouvez utiliser SkyDrive pour cela. Toutefois, pour des raisons de contenu et d’accès, je vous prie d’essayer aussi d’écrire le texte de l’article dans le forum.

     

    Cordialement,

    Alex

    ________________

    Publiez un article sur MSDN !

    Windows Phone 7

    Astuces pour Visual Studio 2010

    XNA – Développement jeux vidéo

    Didacticiels et astuces : VB.NET, C#, ASP.NET, .NET Framework, Silverlight, Workflow Foundation, SharePoint, WPF

    Microsoft propose ce service gratuitement, dans le but d'aider les utilisateurs et d'élargir les connaissances générales liées aux produits et technologies Microsoft. Ce contenu est fourni "tel quel" et il n'implique aucune responsabilité de la part de Microsoft.

     

     


    Suivez MSDN sur Twitter 

    mardi 15 février 2011 15:51
  • Bonsoir à tous,

    En fait je cherchais justement le bouton pour uploader le projet, voici donc le lien sur SkyDrive : http://cid-a3a27364f4ef38d8.office.live.com/self.aspx/.Public/MonExtension.rar

    Sinon pour le problème du forum, je ne sais pas si c'est récent, mais en plus du problème de mise en forme, j'ai également le curseur qui disparait (comme en ce moment même) ce qui n'est pas pratique du tout lorsqu'on doit cliquer à tel ou tel endroit... Autre chose encore, selon les moments, toujours lors du clic sur éditer tout le texte devient un code html brut inexploitable et le seule solution est d'actualiser. Ce n'est pas tout, lorsqu'on clique dans un champ contenant le code, on arrive plus a on sortir (que ce soit en cliquant autre part ou avec une touche du clavier, cela dit ça arrive rarement).

    J'ai jamais essayé un autre navigateur par contre et je pense aussi que ce n'est pas l'endroit pour parler de ce problème.

    Anyway, si vous avez d'autres idées/questions sur le fait de créer son extension, je suis à l'écoute.

     


    N'hésitez pas à poser des questions si un problème subsiste ou quelque chose n'est pas clair. Dans l'autre cas, veuillez indiquer que le problème est résolu. Cordialement.
    mardi 15 février 2011 19:37