Programmgesteuertes Codieren und Decodieren einer Dateianlage mithilfe von Visual C# in InfoPath 2003

Zusammenfassung

In Microsoft Office InfoPath 2007 oder In Microsoft Office InfoPath 2003 Service Pack 1 (SP1) können Sie ein Dateianlage-Steuerelement verwenden, um eine Datei an die InfoPath-Formularvorlage anzufügen. Unter bestimmten Umständen möchten Sie die Datei, die an das Dateianlage-Steuerelement angefügt ist, möglicherweise codieren und dann decodieren. In diesem Fall können Sie Microsoft Visual C# verwenden, um eine Encoderklasse und eine Decoderklasse zu erstellen. Anschließend können Sie die Encoder-Klasse und die Decoderklasse verwenden, um die Dateianlage zu codieren und zu decodieren.

Einführung

In diesem Artikel wird erläutert, wie Sie eine Dateianlage programmgesteuert mithilfe von Microsoft Visual C# in InfoPath 2003 codieren und decodieren. Informationen dazu, wie Sie dies in InfoPath 2010 oder InfoPath 2007 tun, finden Sie auf der folgenden Webseite: So codieren und decodieren Sie eine Dateianlage programmgesteuert mithilfe von Visual C# in InfoPath 2010 oder InfoPath 2007 .

Weitere Informationen

Die Verwendung der hier aufgeführten Informationen, Makro- oder Programmcodes geschieht auf Ihre eigene Verantwortung. Microsoft stellt Ihnen diese Informationen sowie Makro- und Programmlistings ohne Gewähr auf Richtigkeit, Vollständigkeit und/oder Funktionsfähigkeit sowie ohne Anspruch auf Support zur Verfügung. Die zur Verfügung gestellten Makro- und Programmierungsbeispiele sollen lediglich exemplarisch die Funktionsweise des Beispiels aufzeigen. Die Microsoft Support-Spezialisten können bei der Erläuterung der Funktionalität bestimmter Prozeduren helfen, jedoch werden sie diese Beispiele nicht in Bezug auf eine erweiterte Funktionalität verändern, noch werden sie Prozeduren entwickeln, die auf Ihre besonderen Bedürfnisse zugeschnitten sind.

Erstellen eines Visual C#-InfoPath 2003-Projekts

  1. Starten Sie Microsoft Visual Studio .NET 2003.

  2. Klicken Sie im Menü Datei auf Neu, und klicken Sie dann auf Projekt.

  3. Klicken Sie im Dialogfeld "Neues Projekt " im Ordner "Microsoft Office InfoPath-Projekte" auf "Visual C#-Projekte ".

  4. Geben Sie im Feld "Name " "AttachmentEncoding" ein, und klicken Sie dann auf "OK".

  5. Klicken Sie im Microsoft Office-Projekt-Assistenten auf "Neue Formularvorlage erstellen" und dann auf "Fertig stellen".

    Der Microsoft Office Project-Assistent erstellt ein neues Visual Studio .NET 2003-Projekt mit dem Namen AttachmentEncoding. Außerdem wird eine InfoPath-Formularvorlage erstellt. Die InfoPath-Formularvorlage heißt AttachmentEncoding.

Erstellen einer Encoderklasse in Visual Studio .NET 2003

  1. Klicken Sie in Projektmappen-Explorer mit der rechten Maustaste auf "AttachmentEncoding", zeigen Sie auf "Hinzufügen", und klicken Sie dann auf "Neues Element hinzufügen".
  2. Klicken Sie im Dialogfeld "Neues Element hinzufügen" im Vorlagenbereich auf "Klasse", geben Sie "InfoPathAttachmentEncoder.cs" in das Feld "Name" ein, und klicken Sie dann auf "Öffnen".
  3. Ersetzen Sie den gesamten Code in der Datei "InfoPathAttachmentEncoder.cs" durch den folgenden Code.
    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());
    }
    }
    }
    

Erstellen einer Decoderklasse in Visual Studio .NET 2003

  1. Klicken Sie in Projektmappen-Explorer mit der rechten Maustaste auf "AttachmentEncoding", zeigen Sie auf "Hinzufügen", und klicken Sie dann auf "Neues Element hinzufügen".
  2. Klicken Sie im Dialogfeld "Neues Element hinzufügen" im Vorlagenbereich auf "Klasse", geben Sie "InfoPathAttachmentDecoder.cs" in das Feld "Name" ein, und klicken Sie dann auf "Öffnen".
  3. Ersetzen Sie den gesamten Code in der Datei "InfoPathAttachmentDecoder.cs" durch den folgenden Code.
    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; }
    }
    }
    }
    
    

Hinzufügen eines Dateianlage-Steuerelements und eines Textfeld-Steuerelements zum InfoPath-Formular

  1. Klicken Sie in der InfoPath-Formularvorlage "AttachmentEncoding" im Aufgabenbereich "Entwurfsaufgaben" auf "Steuerelemente".
  2. Klicken Sie im Aufgabenbereich "Steuerelemente" unter "Steuerelemente einfügen" auf "Dateianlage".
  3. Klicken Sie mit der rechten Maustaste auf das Steuerelement "Dateianlage ", und klicken Sie dann auf "Dateianlageneigenschaften".
  4. Geben Sie im Dialogfeld "Dateianlageneigenschaften " das Feld "AttachmentField" in das Feld "Feldname " ein, und klicken Sie dann auf "OK".
  5. Klicken Sie im Aufgabenbereich "Steuerelemente" unter "Steuerelemente einfügen" auf "Textfeld".
  6. Klicken Sie mit der rechten Maustaste auf das Textfeld-Steuerelement , und klicken Sie dann auf "Textfeldeigenschaften".
  7. Geben Sie im Dialogfeld " Eigenschaften " des Textfelds "AttachmentName" in das Feld "Feldname " ein, und klicken Sie dann auf "OK".

Hinzufügen einer Schaltfläche "Anfügen" zum InfoPath-Formular

  1. Klicken Sie im Aufgabenbereich "Steuerelemente" unter "Steuerelemente einfügen" auf "Schaltfläche".
  2. Klicken Sie mit der rechten Maustaste auf das neue Schaltflächensteuerelement, und klicken Sie dann auf "Schaltflächeneigenschaften".
  3. Geben Sie im Dialogfeld "Schaltflächeneigenschaften " im Feld "Bezeichnung " "Anfügen" ein, geben Sie "btnAttach" in das ID-Feld ein, und klicken Sie dann auf "Formularcode bearbeiten".
  4. Fügen Sie der btnAttach_OnClick-Methode den folgenden Code hinzu.
    //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();
    }
    
    

Hinzufügen einer Schaltfläche "Speichern" zum InfoPath-Formular

  1. Wechseln Sie zur InfoPath-Formularvorlage "AttachmentEncoding".
  2. Klicken Sie im Aufgabenbereich "Steuerelemente" unter "Steuerelemente einfügen" auf "Schaltfläche".
  3. Klicken Sie mit der rechten Maustaste auf das neue Schaltflächensteuerelement, und klicken Sie dann auf "Schaltflächeneigenschaften".
  4. Geben Sie im Dialogfeld "Schaltflächeneigenschaften " im Feld "Beschriftung " "Speichern" ein, geben Sie "btnSave" in das ID-Feld ein, und klicken Sie dann auf " Formularcode bearbeiten".
  5. Fügen Sie der btnSave-_OnClick-Methode den folgenden Code hinzu.
    //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>");
    }
    
    

Hinweis

Ersetzen Sie in diesem Code den Speicherort, an dem Die Datei gespeichert werden soll.

Stellen Sie sicher, dass die InfoPath-Formularvorlage voll vertrauenswürdig ist.

Bevor Sie dieses Formular testen können, muss die InfoPath-Formularvorlage voll vertrauenswürdig sein. Sie können eine der folgenden Methoden verwenden, um sicherzustellen, dass die InfoPath-Formularvorlage voll vertrauenswürdig ist:

  • Verwenden Sie das Microsoft .NET Framework 1.1-Konfigurationsdienstprogramm, um Voll vertrauenswürdigen Berechtigungen nur Ihrem Visual C#-Code zu gewähren.

  • Verwenden Sie das Hilfsprogramm RegForm aus dem InfoPath Software Development Kit (SDK), um das Formular zu einem voll vertrauenswürdigen Formular zu machen. Dadurch erhalten Sie Voll vertrauenswürdige Berechtigungen für Ihren Visual C#-Code.

  • Verwenden Sie ein Codesignaturzertifikat, um die Formularvorlagendatei (XSN) digital zu signieren. Wenn Sie ein Codesignaturzertifikat verwenden, um die Formularvorlagendatei digital zu signieren, werden benutzer aufgefordert, dem Formular zu vertrauen, wenn sie das Formular öffnen. Dadurch wird das Formular vollständig vertrauenswürdig. Daher werden Ihrem Visual C#-Code voll vertrauenswürdige Berechtigungen gewährt.

  • Verwenden Sie das IPFullTrust-Makro aus dem InfoPath SDK, um das Formular zu einem voll vertrauenswürdigen Formular zu machen. Das IPFullTrust-Makro automatisiert das Festlegen der Manifestdatei (XSF) und der Formularvorlagendatei im InfoPath-Projekt für voll vertrauenswürdig, und dann registriert das IPFullTrust-Makro automatisch die Formularvorlage.

    Weitere Informationen zum Installieren und Verwenden des Makros finden Sie auf der folgenden Microsoft Developer Network (MSDN)-Website:

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

  • Verwenden Sie die externe Automatisierung in InfoPath, um die RegisterSolution-Methode aufzurufen. In der Regel wird diese Methode nur für die Formularentwicklung verwendet, da ein registriertes Formular nur für einen einzelnen Computer registriert wird. Für alle zusätzlichen Formulare müssen andere Benutzer die zusätzlichen Formulare auf ihren eigenen Computern registrieren. Wir empfehlen diese Methode nicht für zusätzliche Formulare. Wir empfehlen eine der vorherigen Methoden, wenn Sie das Formular veröffentlichen.

Da sich dieses Formular in der Formularentwicklung befindet, können Sie die letzte Methode verwenden. Suchen Sie dazu die InfoPath-Formularvorlage "AttachmentEncoding", und führen Sie dann die folgenden Schritte aus:

  1. Klicken Sie im Menü Extras auf Formularoptionen .

  2. Klicken Sie auf die Registerkarte Sicherheit.

  3. Klicken Sie, um das Kontrollkästchen " Sicherheitsstufe automatisch bestimmen" basierend auf dem (empfohlenen) Entwurf des Formulars zu deaktivieren.

    Hinweis InfoPath kann Geschäftslogik, die Voll vertrauenswürdige Berechtigungen erfordert, nicht automatisch erkennen. Daher müssen Sie explizit Voll vertrauenswürdige Berechtigungen erteilen.

  4. Klicken Sie auf "Voll vertrauenswürdig" und dann auf "OK".

  5. Schließen Sie die InfoPath-Formularvorlage "AttachmentEncoding". Wenn Sie aufgefordert werden, Änderungen zu speichern, klicken Sie auf "Ja".

    Hinweis Schließen Sie das Visual Studio .NET 2003-Projekt nicht.

  6. Doppelklicken Sie in Visual Studio .NET 2003 auf die Datei "Manifest.xsf" in Projektmappen-Explorer. Die Datei Manifest.xsf wird geöffnet.

  7. Suchen Sie im Stammknoten das publishUrl-Attribut. Entfernen Sie das publishUrl-Attribut und den Wert des publishUrl-Attributs.

  8. Speichern Sie Ihre Änderungen, und schließen Sie dann die Datei Manifest.xsf.

  9. Klicken Sie auf "Start", dann auf " Ausführen", geben Sie "Editor" ein, und klicken Sie dann auf "OK".

  10. Fügen Sie der leeren Textdatei den folgenden Code hinzu.

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

    Hinweis Ersetzen Sie in diesem Code project_folder_url durch den Pfad der Datei "Manifest.xsf" in Ihrem Projektordner. Denken Sie daran, den Pfad der Datei "Manifest.xsf" zu escapen. Alle einzelnen umgekehrten Schrägstriche (\) im Pfad müssen durch zwei umgekehrte Schrägstriche (\\) ersetzt werden.

  11. Speichern Sie die Datei "Manifest.xsf" auf dem Computer als Register.js Datei.

  12. Um die RegisterSolution-Methode aufzurufen, doppelklicken Sie auf die Register.js Datei, die Sie erstellt haben.

Testen des Formulars

  1. Klicken Sie im AttachmentEncoding Visual Studio .NET 2003-Projekt im Menü "Debuggen" auf "Start". Dadurch wird das InfoPath-Formular im Vorschaumodus gestartet.

  2. Geben Sie im InfoPath-Formular den Pfad der Datei, die Sie anfügen möchten, in das Textfeld ein, und klicken Sie dann auf "Anfügen".

    Hinweis Doppelklicken Sie auf das Dateianlagen-Steuerelement , um zu überprüfen, ob die Datei ordnungsgemäß codiert ist.

  3. Klicken Sie auf Speichern. Suchen Sie den Pfad, den Sie im Abschnitt "Schaltfläche ' Speichern ' zum InfoPath-Formular hinzufügen' angegeben haben.

  4. Um den Test zu beenden, klicken Sie auf "Vorschau schließen".

References

Weitere Informationen zum Headerformat für Dateianlagen finden Sie auf der folgenden MSDN-Website:

Anfügen von Dateien in InfoPath 2003 https://msdn.microsoft.com/en-us/library/aa168351(office.11).aspx