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

Résumé

Dans Microsoft InfoPath 2010 ou dans Microsoft Office InfoPath 2007, 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 encoderclasse et une décodeur. Vous pouvez ensuite utiliser encoderclass et Decoderclass pour encoder et décoder la pièce jointe du fichier. Cet article explique comment concevoir un modèle de formulaire InfoPath qui encode un fichier pour pièce jointe au formulaire et décode la pièce jointe à enregistrer dans le système de fichiers.  

Pour plus d’informations sur la procédure à suivre dans InfoPath 2003, cliquez sur le numéro d’article suivant pour afficher l’article dans la Base de connaissances Microsoft :

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

Informations supplémentaires

Microsoft fournit des exemples de programmation à des fins d’illustration uniquement, sans garantie explicite ou implicite, y compris, de manière non limitative, les garanties implicites de qualité marchande et/ou d’adéquation à un usage particulier. Cet article suppose 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.

Dans l’exemple suivant, vous allez suivre les étapes suivantes :

  1. Créez un formulaire qui inclut un projet Visual C#.
  2. Créez une classe Encoderclass.
  3. Créez une décodeurclasse.
  4. Modifiez le formulaire pour appeler le code.
  5. Testez les opérations de code dans le formulaire.

Créer un formulaire qui inclut un projet Visual C#

Créez un modèle de formulaire et un projet à l’aide des instructions de la version d’InfoPath que vous utilisez.

InfoPath 2010

  1. Dans InfoPath Designer, créez un modèle de formulaire vide, puis cliquez sur l’icône Enregistrer.
  2. Lorsque vous y êtes invité, tapez le nom du fichier, puis cliquez sur Enregistrer.
  3. Cliquez sur l’onglet **Développeur **, puis sur Langue.
  4. Sous Langage de code du modèle de formulaire, sélectionnez C#, puis cliquez sur OK.

InfoPath 2007

  1. Dans le menu **Fichier **, cliquez sur Concevoir un modèle de formulaire.
  2. Dans le volet **Concevoir un modèle de formulaire**, cliquez sur Vide , puis sur OK.
  3. Dans le menu Fichier, cliquez sur Enregistrer.
  4. Lorsque vous y êtes invité, tapez le nom de fichier InfoPathAttachmentEncoding, puis cliquez sur Enregistrer.
  5. Dans le menu Outils, cliquez sur Options de formulaire.
  6. Sous Catégorie dans la boîte de dialogue **Options de formulaire **, cliquez sur Programmation.
  7. Sous Langage de programmation, dans la liste du langage de code du modèle de formulaire , sélectionnez C#, puis cliquez sur OK.

Créer une classe Encoder

Créez une classe Encoderclass en utilisant les instructions de la version d’InfoPath que vous utilisez.

InfoPath 2010

  1. Sous l’onglet Développeur, cliquez sur **Éditeur de code **pour démarrer l’éditeur Visual Studio Tools for Applications (VSTA).
  2. Dans le menu Projet , cliquez sur Ajouter un nouvel élément.
  3. Cliquez pour sélectionner Classe.
  4. Dans le champ Nom , remplacez le nom par InfoPathAttachmentEncoder.cs, puis cliquez sur Enregistrer.
  5. Dans la fenêtre de code, remplacez le code existant par le code de la section « Code encodeur » suivante.

InfoPath 2007

  1. Démarrez l’éditeur Visual Studio Tools for Applications (VSTA). 
  2. Dans le volet **Explorateur de projets **, cliquez avec le bouton droit sur InfoPathAttachmentEncoding, cliquez sur Ajouter, puis sur Nouvel élément.
  3. Dans la section Modèles , sélectionnez Classe, remplacez le nom par InfoPathAttachmentEncoder.cs, puis cliquez sur Ajouter.
  4. Dans la fenêtre de code, collez le code de la section « Code encodeur » suivante.

Code de l’encodeur

Utilisez le code suivant dans InfoPath 2010 ou InfoPath 2007 :

using System;
using System.IO;
using System.Text;
using System.Security.Cryptography;
using InfoPathAttachmentEncoding;

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();

// Obtain 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

Créez une décodeurclasse en utilisant les instructions de la version d’InfoPath que vous utilisez.

InfoPath 2010

  1. Dans l’Éditeur de code, dans le menu Projet , cliquez sur Ajouter un nouvel élément, puis cliquez pour sélectionner Classe.
  2. Dans le champ Nom , remplacez le nom par InfoPathAttachmentDecoder.cs, puis cliquez sur Enregistrer.
  3. Dans la fenêtre de code, remplacez le code existant par le code de la section « Code décodeur » suivante. 

InfoPath 2007

  1. Dans VSTA, dans le volet **Explorateur de projets **, cliquez avec le bouton droit sur InfoPathAttachmentEncoding, cliquez sur Ajouter, puis sur Nouvel élément.
  2. Dans la section Modèles , sélectionnez Classe, remplacez le nom par InfoPathAttachmentDecoder.cs, puis cliquez sur Ajouter.
  3. Dans la fenêtre de code, collez le code de la section « Code décodeur » suivante.

Code décodeur

Utilisez le code suivant dans InfoPath 2010 ou InfoPath 2007 :

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 obtain 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.ToString())){
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; }
}
}
}

Modifier le formulaire

Ajoutez un contrôle Pièce jointe de fichier, un contrôle Zone de texte et un contrôle Button au formulaire InfoPath. Pour cela, procédez comme suit :

  1. Ouvrez le volet Office Contrôles en suivant les instructions de la version d’InfoPath que vous utilisez. 

    • InfoPath 2010:In the InfoPathAttachmentEncoding InfoPath form template, under the **Home **tab, expand the **Controls **gallery.
    • InfoPath 2007 :Dans le modèle de formulaire InfoPathAttachmentEncoding InfoPath, cliquez sur Contrôles dans le volet **Tâches de conception **.
  2. Ajoutez un contrôle Pièce jointe au formulaire InfoPath en suivant les instructions de la version d’InfoPath que vous utilisez :

    • InfoPath 2010 :Dans le volet Office Contrôles , sous Objets, cliquez sur Pièce jointe de fichier.
    • InfoPath 2007 :Dans le volet Office Contrôles , sous Fichier et Image, cliquez sur Pièce jointe.
  3. Cliquez avec le bouton droit sur le contrôle **Pièce jointe **, 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 du fichier **, tapez theAttachmentFieldin dans la zone **Nom du champ **, puis cliquez sur OK.

  5. Ajoutez un contrôle Zone de texte au formulaire InfoPath en utilisant les instructions de la version d’InfoPath que vous utilisez :

    • InfoPath 2010 : Dans le volet Office Contrôles , sous Entrée, cliquez sur Zone de texte.
    • InfoPath 2007 : Dans le volet Office Contrôles , sous Standard, cliquez sur Zone de texte.
  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.

  8. Ajoutez un bouton Attacher au formulaire InfoPath en utilisant les instructions de la version d’InfoPath que vous utilisez :

    • InfoPath 2010 : Dans le volet Office Contrôles , sous Objets, cliquez sur Bouton.
    • InfoPath 2007 : Dans le volet Office Contrôles , sous Standard, cliquez sur Bouton.
  9. Cliquez avec le bouton droit sur le nouveau contrôle Button, puis cliquez sur Propriétés du bouton.

  10. 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 du formulaire.

  11. Accédez au haut de la fenêtre de code, puis ajoutez la ligne de code suivante :

    using InfoPathAttachmentEncoding;
    
  12. Revenez à « écrire votre code ici », puis ajoutez le code suivant :

     //Create an XmlNamespaceManager
     XmlNamespaceManager ns = this.NamespaceManager;
    
    //Create an XPathNavigator object for the Main data source
     XPathNavigator xnMain = this.MainDataSource.CreateNavigator();
    
    //Create an XPathNavigator object for the attachment node
     XPathNavigator xnAttNode = xnMain.SelectSingleNode("/my:myFields/my:theAttachmentField", ns);
    
    //Create an XPathNavigator object for the filename node
     XPathNavigator xnFileName = xnMain.SelectSingleNode("/my:myFields/my:theAttachmentName", ns);
    
    //Obtain the text of the filename node.
     string fileName = xnFileName.Value;
     if (fileName.Length > 0)
     {
      //Encode the file and assign it to the attachment node.
      InfoPathAttachmentEncoder myEncoder = new InfoPathAttachmentEncoder(fileName);
    
    //Check for the "xsi:nil" attribute on the file attachment node and remove it
      //before setting the value to attach the filerRemove the "nil" attribute
      if (xnAttNode.MoveToAttribute("nil", "http://www.w3.org/2001/XMLSchema-instance"))
       xnAttNode.DeleteSelf();
    
    //Attach the file
      xnAttNode.SetValue(myEncoder.ToBase64String());
     }              
    
    

Ajouter un bouton Enregistrer au formulaire InfoPath

  1. Revenez au modèle de formulaire InfoPathAttachmentEncoding.

  2. Ajoutez un bouton Enregistrer en suivant les instructions de la version d’InfoPath que vous utilisez :

    • InfoPath 2010 : Dans le volet Office Contrôles , sous Objets, cliquez sur Bouton.
    • InfoPath 2007 : Dans le volet Office Contrôles , sous Standard, cliquez sur Bouton.
  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. Insérez le code suivant :

     //Create an XmlNamespaceManager
     XmlNamespaceManager ns = this.NamespaceManager;
    
    //Create an XPathNavigator object for the Main data source
     XPathNavigator xnMain = this.MainDataSource.CreateNavigator();
    
    //Create an XPathNavigator object for the attachment node
     XPathNavigator xnAttNode = xnMain.SelectSingleNode("/my:myFields/my:theAttachmentField", ns);
    
    //Obtain the text of the node.
     string theAttachment = xnAttNode.Value;
     if(theAttachment.Length > 0)
     {
         InfoPathAttachmentDecoder myDecoder = new InfoPathAttachmentDecoder(theAttachment);
         myDecoder.SaveAttachment(@"Path to the folder to save the attachment");
     }                                              
    
    

Remarque

Dans ce code, le chemin d’accès de l’espace réservé au dossier pour enregistrer la pièce jointe représente l’emplacement dans lequel vous souhaitez enregistrer le fichier.

Cliquez sur l’icône Enregistrer, puis fermez VSTA.

Tester le formulaire

Pour que ce formulaire puisse joindre un fichier, le modèle de formulaire InfoPath doit être entièrement approuvé. Pour vous en assurer, effectuez l’une des actions suivantes :

  • Utilisez un certificat de signature de code pour signer numériquement le fichier de modèle de formulaire (.xsn). Dans ce cas, 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#.
  • Créez un modèle installable.

Une fois que vous vous êtes assuré que le modèle de formulaire est entièrement approuvé, vous devez le tester. Pour cela, procédez comme suit :

  1. Ouvrez le formulaire en mode Aperçu en suivant les étapes de la version d’InfoPath que vous utilisez :

    • InfoPath 2010 Sous l’onglet Accueil , cliquez sur Aperçu.
    • InfoPath 2007 Dans la barre Standardtoolbar, cliquez sur 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 encodé correctement. 

  3. Cliquez sur Enregistrer.

  4. Recherchez le chemin d’accès que vous avez fourni dans le code de la section « Ajouter un bouton Enregistrer au formulaire InfoPath », puis vérifiez que le fichier a été enregistré dans ce dossier. 

  5. Cliquez sur Fermer l’aperçu. Cela met fin au test.