Comment encoder et décoder une pièce jointe de fichier par programmation à l’aide de Visual C# dans InfoPath 2003

Résumé

Dans Microsoft Office InfoPath 2007 ou Dans Microsoft Office InfoPath 2003 Service Pack 1 (SP1), vous pouvez utiliser un contrôle pièce jointe de fichier pour attacher un fichier au modèle de formulaire InfoPath. Dans des circonstances spécifiques, vous souhaiterez peut-être encoder puis décoder le fichier attaché au contrôle Pièce jointe . Dans ce cas, vous pouvez utiliser Microsoft Visual C# pour créer une classe Encodeur et une classe de décodeur. Vous pouvez ensuite utiliser la classe Encoder et la classe Decoder pour encoder et décoder la pièce jointe du fichier.

Introduction

Cet article explique comment encoder et décoder une pièce jointe de fichier par programmation à l’aide de Microsoft Visual C# dans InfoPath 2003. Pour plus d’informations sur la procédure à suivre dans InfoPath 2010 ou InfoPath 2007, consultez la page web suivante : Comment encoder et décoder une pièce jointe de fichier par programmation à l’aide de Visual C# dans InfoPath 2010 ou Dans InfoPath 2007 .

Informations supplémentaires

Microsoft fournit des exemples de programmation à titre d'illustration uniquement, sans garantie expresse ou implicite. Cela inclut, sans y être limité, les garanties implicites de commercialisation et d'adaptation à un but en particulier. Cet article considère que vous connaissez le langage de programmation présenté et les outils utilisés pour créer et déboguer des procédures. Les techniciens du Support technique Microsoft peuvent vous expliquer les fonctionnalités d'une procédure particulière, mais ils ne peuvent pas modifier les exemples en vue de vous fournir des fonctionnalités supplémentaires ou de créer des procédures répondant à vos besoins spécifiques.

Créer un projet Visual C# InfoPath 2003

  1. Démarrez Microsoft Visual Studio .NET 2003.

  2. Dans le menu Fichier, cliquez sur Nouveau, puis sur Projet.

  3. Dans la boîte de dialogue Nouveau projet , cliquez sur Projets Visual C# dans le dossier Microsoft Office InfoPath Projects.

  4. Dans la zone Nom , tapez AttachmentEncoding, puis cliquez sur OK.

  5. Dans l’Assistant Projet Microsoft Office, cliquez sur Créer un modèle de formulaire, puis cliquez sur Terminer.

    L’Assistant Projet Microsoft Office crée un projet Visual Studio .NET 2003 nommé AttachmentEncoding. Un modèle de formulaire InfoPath est également créé. Le modèle de formulaire InfoPath est nommé AttachmentEncoding.

Créer une classe Encoder dans Visual Studio .NET 2003

  1. Dans Explorateur de solutions, cliquez avec le bouton droit sur AttachmentEncoding, pointez sur Ajouter, puis cliquez sur Ajouter un nouvel élément.
  2. Dans la boîte de dialogue Ajouter un nouvel élément , cliquez sur Classe dans le volet Modèle , tapez InfoPathAttachmentEncoder.cs dans la zone Nom , puis cliquez sur Ouvrir.
  3. Remplacez tout le code du fichier InfoPathAttachmentEncoder.cs par le code suivant.
    using System;
    using System.IO;
    using System.Text;
    using System.Security.Cryptography;
    
    namespace InfoPathAttachmentEncoding
    {
    /// <summary>
    /// InfoPathAttachment encodes file data into the format expected by InfoPath for use in file attachment nodes.
    /// </summary>
    public class InfoPathAttachmentEncoder
    {
    private string base64EncodedFile = string.Empty;
    private string fullyQualifiedFileName;
    
    /// <summary>
    /// Creates an encoder to create an InfoPath attachment string.
    /// </summary>
    /// <param name="fullyQualifiedFileName"></param>
    public InfoPathAttachmentEncoder(string fullyQualifiedFileName)
    {
    if (fullyQualifiedFileName == string.Empty)
    throw new ArgumentException("Must specify file name", "fullyQualifiedFileName");
    
    if (!File.Exists(fullyQualifiedFileName))
    throw new FileNotFoundException("File does not exist: " + fullyQualifiedFileName, fullyQualifiedFileName);
    
    this.fullyQualifiedFileName = fullyQualifiedFileName;
    }
    
    /// <summary>
    /// Returns a Base64 encoded string.
    /// </summary>
    /// <returns>String</returns>
    public string ToBase64String()
    {
    if (base64EncodedFile != string.Empty)
    return base64EncodedFile;
    
    // This memory stream will hold the InfoPath file attachment buffer before Base64 encoding.
    MemoryStream ms = new MemoryStream();
    
    // Get the file information.
    using (BinaryReader br = new BinaryReader(File.Open(fullyQualifiedFileName, FileMode.Open, FileAccess.Read, FileShare.Read)))
    {
    string fileName = Path.GetFileName(fullyQualifiedFileName);
    
    uint fileNameLength = (uint)fileName.Length + 1;
    
    byte[] fileNameBytes = Encoding.Unicode.GetBytes(fileName);
    
    using (BinaryWriter bw = new BinaryWriter(ms))
    {
    // Write the InfoPath attachment signature. 
    bw.Write(new byte[] { 0xC7, 0x49, 0x46, 0x41 });
    
    // Write the default header information.
    bw.Write((uint)0x14);// size
    bw.Write((uint)0x01);// version
    bw.Write((uint)0x00);// reserved
    
    // Write the file size.
    bw.Write((uint)br.BaseStream.Length);
    
    // Write the size of the file name.
    bw.Write((uint)fileNameLength);
    
    // Write the file name (Unicode encoded).
    bw.Write(fileNameBytes);
    
    // Write the file name terminator. This is two nulls in Unicode.
    bw.Write(new byte[] {0,0});
    
    // Iterate through the file reading data and writing it to the outbuffer.
    byte[] data = new byte[64*1024];
    int bytesRead = 1;
    
    while (bytesRead > 0)
    {
    bytesRead = br.Read(data, 0, data.Length);
    bw.Write(data, 0, bytesRead);
    }
    }
    }
    
    // This memorystream will hold the Base64 encoded InfoPath attachment.
    MemoryStream msOut = new MemoryStream();
    
    using (BinaryReader br = new BinaryReader(new MemoryStream(ms.ToArray())))
    {
    // Create a Base64 transform to do the encoding.
    ToBase64Transform tf = new ToBase64Transform();
    
    byte[] data = new byte[tf.InputBlockSize];
    byte[] outData = new byte[tf.OutputBlockSize];
    
    int bytesRead = 1;
    
    while (bytesRead > 0)
    {
    bytesRead = br.Read(data, 0, data.Length);
    
    if (bytesRead == data.Length)
    tf.TransformBlock(data, 0, bytesRead, outData, 0);
    else
    outData = tf.TransformFinalBlock(data, 0, bytesRead);
    
    msOut.Write(outData, 0, outData.Length);
    }
    }
    
    msOut.Close();
    
    return base64EncodedFile = Encoding.ASCII.GetString(msOut.ToArray());
    }
    }
    }
    

Créer une classe de décodeur dans Visual Studio .NET 2003

  1. Dans Explorateur de solutions, cliquez avec le bouton droit sur AttachmentEncoding, pointez sur Ajouter, puis cliquez sur Ajouter un nouvel élément.
  2. Dans la boîte de dialogue Ajouter un nouvel élément , cliquez sur Classe dans le volet Modèle , tapez InfoPathAttachmentDecoder.cs dans la zone Nom , puis cliquez sur Ouvrir.
  3. Remplacez tout le code du fichier InfoPathAttachmentDecoder.cs par le code suivant.
    using System;
    using System.IO;
    using System.Text;
    
    namespace InfoPathAttachmentEncoding
    {
    /// <summary>
    /// Decodes a file attachment and saves it to a specified path.
    /// </summary>
    public class InfoPathAttachmentDecoder
    {
    private const int SP1Header_Size = 20;
    private const int FIXED_HEADER = 16;
    
    private int fileSize;
    private int attachmentNameLength;
    private string attachmentName;
    private byte[] decodedAttachment;
    
    /// <summary>
    /// Accepts the Base64 encoded string
    /// that is the attachment.
    /// </summary>
    public InfoPathAttachmentDecoder(string theBase64EncodedString)
    {
    byte [] theData = Convert.FromBase64String(theBase64EncodedString);
    using(MemoryStream ms = new MemoryStream(theData))
    {
    BinaryReader theReader = new BinaryReader(ms);
    DecodeAttachment(theReader);
    }
    }
    
    private void DecodeAttachment(BinaryReader theReader)
    {
    //Position the reader to get the file size.
    byte[] headerData = new byte[FIXED_HEADER];
    headerData = theReader.ReadBytes(headerData.Length);
    
    fileSize = (int)theReader.ReadUInt32();
    attachmentNameLength = (int)theReader.ReadUInt32() * 2;
    
    byte[] fileNameBytes = theReader.ReadBytes(attachmentNameLength);
    //InfoPath uses UTF8 encoding.
    Encoding enc = Encoding.Unicode;
    attachmentName = enc.GetString(fileNameBytes, 0, attachmentNameLength - 2);
    decodedAttachment = theReader.ReadBytes(fileSize);
    }
    
    public void SaveAttachment(string saveLocation)
    {
    string fullFileName = saveLocation;
    if(!fullFileName.EndsWith(Path.DirectorySeparatorChar))
    {
    fullFileName += Path.DirectorySeparatorChar;
    }
    
    fullFileName += attachmentName;
    
    if(File.Exists(fullFileName))
    File.Delete(fullFileName);
    
    FileStream fs = new FileStream(fullFileName, FileMode.CreateNew);
    BinaryWriter bw = new BinaryWriter(fs);
    bw.Write(decodedAttachment);
    
    bw.Close();
    fs.Close();
    }
    
    public string Filename
    {
    get{ return attachmentName; }
    }
    
    public byte[] DecodedAttachment
    {
    get{ return decodedAttachment; }
    }
    }
    }
    
    

Ajouter un contrôle Pièce jointe de fichier et un contrôle Zone de texte au formulaire InfoPath

  1. Dans le modèle de formulaire InfoPath AttachmentEncoding, cliquez sur Contrôles dans le volet Tâches de conception.
  2. Dans le volet Office Contrôles , cliquez sur Pièce jointe sous Contrôles d’insertion.
  3. Cliquez avec le bouton droit sur le contrôle Pièce jointe de fichier, puis cliquez sur Propriétés de la pièce jointe du fichier.
  4. Dans la boîte de dialogue Propriétés de la pièce jointe de fichier , tapez theAttachmentField dans la zone Nom du champ , puis cliquez sur OK.
  5. Dans le volet Office Contrôles , cliquez sur Zone de texte sous Contrôles d’insertion.
  6. Cliquez avec le bouton droit sur le contrôle Zone de texte, puis cliquez sur Propriétés de la zone de texte.
  7. Dans la boîte de dialogue Propriétés de la zone de texte, tapez theAttachmentName dans la zone Nom du champ , puis cliquez sur OK.

Ajouter un bouton Attacher au formulaire InfoPath

  1. Dans le volet Office Contrôles , cliquez sur Bouton sous Insérer des contrôles.
  2. Cliquez avec le bouton droit sur le nouveau contrôle Button , puis cliquez sur Propriétés du bouton.
  3. Dans la boîte de dialogue Propriétés du bouton , tapez Attacher dans la zone Étiquette , tapez btnAttach dans la zone ID , puis cliquez sur Modifier le code de formulaire.
  4. Ajoutez le code suivant à la méthode btnAttach_OnClick.
    //Get a reference to the attachment node.
    IXMLDOMNode theAttachmentNode = thisXDocument.DOM.selectSingleNode("my:myFields/my:theAttachmentField");
    
    //Get a reference to the filename node.
    IXMLDOMNode fileNameNode = thisXDocument.DOM.selectSingleNode("my:myFields/my:theAttachmentName");
    //Get the text of the node.
    String fileName = fileNameNode.text;
    if(fileName.Length > 0)
    {
    //Encode the file and assign it to the attachment node.
    InfoPathAttachmentEncoding.Encoder myEncoder = new InfoPathAttachmentEncoding.Encoder(fileName);
    if(theAttachmentNode.attributes.getNamedItem("xsi:nil") != null)
    theAttachmentNode.attributes.removeNamedItem("xsi:nil");
    theAttachmentNode.text = myEncoder.ToBase64String();
    }
    
    

Ajouter un bouton Enregistrer au formulaire InfoPath

  1. Basculez vers le modèle de formulaire InfoPath AttachmentEncoding.
  2. Dans le volet Office Contrôles , cliquez sur Bouton sous Insérer des contrôles.
  3. Cliquez avec le bouton droit sur le nouveau contrôle Button , puis cliquez sur Propriétés du bouton.
  4. Dans la boîte de dialogue Propriétés du bouton , tapez Enregistrer dans la zone Étiquette , tapez btnSave dans la zone ID , puis cliquez sur Modifier le code du formulaire.
  5. Ajoutez le code suivant à la méthode btnSave _OnClick.
    //Get a reference to the attachment node.
    IXMLDOMNode n = thisXDocument.DOM.selectSingleNode("my:myFields/my:theAttachmentField");
    //Get the text of the node.
    String theAttachment = n.text;
    if(theAttachment.Length > 0)
    {
    InfoPathAttachmentEncoding.Decoder myDecoder = new InfoPathAttachmentEncoding.Decoder(theAttachment);
    myDecoder.SaveAttachment(@"<Path to save the file>");
    }
    
    

Remarque

Dans ce code, remplacez l’emplacement où vous souhaitez enregistrer le fichier.

Assurez-vous que le modèle de formulaire InfoPath est entièrement approuvé

Avant de pouvoir tester ce formulaire, le modèle de formulaire InfoPath doit être entièrement approuvé. Vous pouvez utiliser l’une des méthodes suivantes pour vous assurer que le modèle de formulaire InfoPath est entièrement approuvé :

  • Utilisez l’utilitaire de configuration Microsoft .NET Framework 1.1 pour accorder des autorisations de confiance totale uniquement à votre code Visual C#.

  • Utilisez l’utilitaire RegForm du Kit de développement logiciel (SDK) InfoPath pour faire du formulaire un formulaire entièrement approuvé. Cela accorde des autorisations d’approbation totale à votre code Visual C#.

  • Utilisez un certificat de signature de code pour signer numériquement le fichier de modèle de formulaire (.xsn). Lorsque vous utilisez un certificat de signature de code pour signer numériquement le fichier de modèle de formulaire, les utilisateurs sont invités à approuver le formulaire lorsqu’ils ouvrent le formulaire. Cela rend le formulaire entièrement fiable. Par conséquent, des autorisations d’approbation totale sont accordées à votre code Visual C#.

  • Utilisez la macro IPFullTrust du Kit de développement logiciel (SDK) InfoPath pour faire du formulaire un formulaire entièrement approuvé. La macro IPFullTrust automatise la définition du fichier manifeste (.xsf) et du fichier de modèle de formulaire dans le projet InfoPath pour une confiance totale, puis la macro IPFullTrust inscrit automatiquement le modèle de formulaire.

    Pour plus d’informations sur l’installation et l’utilisation de la macro, visitez le site web Microsoft Developer Network (MSDN) suivant :

    https://msdn.microsoft.com/en-us/library/aa202736(office.11).aspx

  • Utilisez l’automatisation externe dans InfoPath pour appeler la méthode RegisterSolution. En règle générale, cette méthode est utilisée uniquement pour le développement de formulaires, car un formulaire inscrit s’inscrit uniquement pour un ordinateur individuel. Pour tout formulaire supplémentaire, les autres utilisateurs doivent inscrire les formulaires supplémentaires sur leurs propres ordinateurs. Nous ne recommandons pas cette méthode pour les formulaires supplémentaires. Nous vous recommandons l’une des méthodes précédentes lorsque vous publiez le formulaire.

Étant donné que ce formulaire est en cours de développement, vous pouvez utiliser la dernière méthode. Pour ce faire, recherchez le modèle de formulaire InfoPath AttachmentEncoding, puis procédez comme suit :

  1. Dans le menu Outils, cliquez sur Options de formulaire.

  2. Cliquez sur l’onglet Sécurité.

  3. Cliquez pour désactiver la case à cocher Déterminer automatiquement le niveau de sécurité en fonction de la conception (recommandée) du formulaire .

    Note InfoPath ne peut pas détecter automatiquement la logique métier qui nécessite des autorisations de confiance totale. Par conséquent, vous devez accorder explicitement des autorisations de confiance totale.

  4. Cliquez sur Confiance totale, puis sur OK.

  5. Fermez le modèle de formulaire InfoPath AttachmentEncoding. Si vous êtes invité à enregistrer les modifications, cliquez sur Oui.

    Note Ne fermez pas le projet Visual Studio .NET 2003.

  6. Dans Visual Studio .NET 2003, double-cliquez sur le fichier Manifest.xsf dans Explorateur de solutions. Le fichier Manifest.xsf s’ouvre.

  7. Dans le nœud racine, recherchez l’attribut publishUrl. Supprimez l’attribut publishUrl et la valeur de l’attribut publishUrl.

  8. Enregistrez vos modifications, puis fermez le fichier Manifest.xsf.

  9. Cliquez sur Démarrer, cliquez sur Exécuter, tapez le Bloc-notes, puis cliquez sur OK.

  10. Ajoutez le code suivant au fichier texte vide.

    oApp = WScript.CreateObject("InfoPath.ExternalApplication");
    strAbsolutePath = "<project_folder_url>\\Manifest.xsf";
    oApp.RegisterSolution(strAbsolutePath,"overwrite"); 
    
    

    Note Dans ce code, remplacez project_folder_url par le chemin d’accès du fichier Manifest.xsf dans le dossier de votre projet. N’oubliez pas d’échapper le chemin du fichier Manifest.xsf. Tous les barres obliques inverses uniques (\) dans le chemin d’accès doivent être remplacés par deux barres obliques inverses (\\).

  11. Enregistrez le fichier Manifest.xsf sur l’ordinateur en tant que fichier Register.js.

  12. Pour appeler la méthode RegisterSolution, double-cliquez sur le fichierRegister.js que vous avez créé.

Tester le formulaire

  1. Dans le projet AttachmentEncoding Visual Studio .NET 2003, cliquez sur Démarrer dans le menu Déboguer . Cela démarre le formulaire InfoPath en mode Aperçu.

  2. Dans le formulaire InfoPath, tapez le chemin d’accès du fichier à joindre dans la zone de texte, puis cliquez sur Attacher.

    Note Double-cliquez sur le contrôle Pièce jointe du fichier pour vérifier que le fichier est correctement encodé.

  3. Cliquez sur Enregistrer. Recherchez le chemin d’accès que vous avez fourni dans la section « Ajouter un bouton Enregistrer au formulaire InfoPath ».

  4. Pour terminer le test, cliquez sur Fermer l’aperçu.

References

Pour plus d’informations sur le format d’en-tête de pièce jointe de fichier, visitez le site web MSDN suivant :

Attachement de fichiers dans InfoPath 2003 https://msdn.microsoft.com/en-us/library/aa168351(office.11).aspx