Como codificar e descodificar um anexo de ficheiro através de programação através do Visual C# no InfoPath 2010 ou no InfoPath 2007

Resumo

No Microsoft InfoPath 2010 ou no Microsoft Office InfoPath 2007, pode utilizar um controlo de Anexo de Ficheiro para anexar um ficheiro ao modelo de formulário do InfoPath. Em circunstâncias específicas, poderá querer codificar e, em seguida, descodificar o ficheiro anexado ao controlo de Anexo de Ficheiro. Neste caso, pode utilizar o Microsoft Visual C# para criar uma CodificaçãoDeCoderclass e uma Decoderclass. Em seguida, pode utilizar a Codificação e a Decoderclass para codificar e descodificar o anexo do ficheiro. Este artigo descreve como estruturar um modelo de formulário do InfoPath que codifica um ficheiro de anexo para o formulário e descodifica o anexo para guardar no sistema de ficheiros.  

Para obter mais informações sobre como fazê-lo no InfoPath 2003, clique no número de artigo seguinte para ver o artigo na Base de Dados de Conhecimento Microsoft:

892730 Como codificar e descodificar um anexo de ficheiro através de programação através do Visual C# no InfoPath

Mais Informações

A Microsoft fornece exemplos de programação apenas para ilustração, sem garantia expressa ou implícita, incluindo, mas não se limitando a, as garantias implícitas de comercialização e/ou aptidão para um propósito específico. Este artigo pressupõe que o utilizador está familiarizado com a linguagem de programação demonstrada e as ferramentas utilizadas para criar e depurar procedimentos. Os técnicos de suporte da Microsoft podem ajudar a explicar a funcionalidade de um determinado procedimento, mas não modificarão estes exemplos para proporcionarem funcionalidades adicionais, nem criarão procedimentos adaptados às suas necessidades específicas.

No exemplo seguinte, irá seguir estes passos:

  1. Crie um formulário que inclua um projeto visual C#.
  2. Criar uma Codificação.
  3. Criar uma Decoderclass.
  4. Modifique o formulário para chamar o código.
  5. Teste as operações de código no formulário.

Criar um formulário que inclua um projeto visual C#

Crie um modelo de formulário e projeto ao utilizar as instruções para a versão do InfoPath que está a utilizar.

InfoPath 2010

  1. No InfoPath Designer, crie um modelo de formulário em branco e, em seguida, clique no ícone Guardar.
  2. Quando lhe for pedido, escreva o nome do ficheiro e, em seguida, clique em Guardar.
  3. Clique no **separador Programador **e, em seguida, clique em Idioma.
  4. Em Idioma do código do modelo de formulário, selecione C# e, em seguida, clique em OK.

InfoPath 2007

  1. No menu **Ficheiro **, clique em Estruturar um Modelo de Formulário.
  2. No **Estruturar um Modelo de Formulário **painel de tarefas, clique em Em Branco e, em seguida, clique em OK.
  3. No menu Ficheiro , clique em Guardar.
  4. Quando lhe for pedido, escreva o nome do ficheiro InfoPathAttachmentEncoding e, em seguida, clique em Guardar.
  5. No menu Ferramentas , clique em Opções de Formulário.
  6. Em Categoria na **Opções de Formulário **caixa de diálogo, clique em Programação.
  7. Em Linguagem de programação, na lista Idioma do código do modelo de formulário, selecione C# e, em seguida, clique em OK.

Criar uma turma de Codificador

Crie uma Codificação utilizando as instruções para a versão do InfoPath que está a utilizar.

InfoPath 2010

  1. No separador Programador, clique em **Editor de Código **para iniciar o editor de Visual Studio Tools for Applications (VSTA).
  2. No menu Projeto , clique em Adicionar Novo Item.
  3. Clique para selecionar Turma.
  4. No campo Nome , altere o nome para InfoPathAttachmentEncoder.cs e, em seguida, clique em Guardar.
  5. Na janela do código, substitua o código existente pelo código da seguinte secção "Código do codificador".

InfoPath 2007

  1. Inicie o Visual Studio Tools for Applications editor de Ações a Fazer (VSTA). 
  2. No **Explorador de Projeto **painel, clique com o botão direito do rato em InfoPathAttachmentEncoding, clique em Adicionar e, em seguida, clique em Novo Item.
  3. Na secção Modelos , selecione Turma, altere o nome para InfoPathAttachmentEncoder.cs e, em seguida, clique em Adicionar.
  4. Na janela do código, colar o código a partir da seguinte secção "Código do codificador".

Código codificador

Utilize o seguinte código no InfoPath 2010 ou no 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());
}
}
}

Criar uma turma de Descodificar

Crie uma Decoderclass ao utilizar as instruções para a versão do InfoPath que está a utilizar.

InfoPath 2010

  1. No Editor de Código, no menu Projeto, clique em Adicionar Novo Item e, em seguida, clique para selecionar Turma.
  2. No campo Nome , altere o nome para InfoPathAttachmentDecoder.cs e, em seguida, clique em Guardar.
  3. Na janela do código, substitua o código existente pelo código a partir da seguinte secção "Código de descodificar". 

InfoPath 2007

  1. No VSTA, no painel **Explorador de Projetos **, clique com o botão direito do rato em InfoPathAttachmentEncoding, clique em Adicionar e, em seguida, clique em Novo Item.
  2. Na secção Modelos , selecione Turma, altere o nome para InfoPathAttachmentDecoder.cs e, em seguida, clique em Adicionar.
  3. Na janela do código, colar o código a partir da seguinte secção "Código de descodificador".

Descodificar código

Utilize o seguinte código no InfoPath 2010 ou no 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; }
}
}
}

Modificar o formulário

Adicione um controlo de Anexo de Ficheiro, um controlo de Caixa de Texto e um controlo de Botão ao formulário do InfoPath. Para tal, siga estes passos:

  1. Abra o painel de tarefas Controlos utilizando as instruções para a versão do InfoPath que está a utilizar. 

    • InfoPath 2010: no modelo de formulário do InfoPathAttachmentEncoding InfoPath, no separador **Home **, expanda a **Controls **gallery.
    • InfoPath 2007:no modelo de formulário do InfoPathAttachmentEncoding InfoPath, clique em Controlos no **Tarefas de Estrutura **painel de tarefas.
  2. Adicione um controlo de Anexo de Ficheiro ao formulário do InfoPath ao utilizar as instruções para a versão do InfoPath que está a utilizar:

    • InfoPath 2010: no painel de tarefas Controlos , em Objetos, clique em Anexo de Ficheiro.
    • InfoPath 2007: no painel de tarefas Controlos , em Ficheiro e Imagem, clique em Anexo de Ficheiro.
  3. Clique com o botão direito do rato no controlo **Anexo de Ficheiro **e, em seguida, clique em Propriedades de Anexo de Ficheiro.

  4. Na caixa de diálogo **Propriedades de Anexo de Ficheiro **, escreva o CampoAttachment na caixa **Nome do Campo **e, em seguida, clique em OK.

  5. Adicione um controlo de Caixa de Texto ao formulário do InfoPath ao utilizar as instruções para a versão do InfoPath que está a utilizar:

    • InfoPath 2010: no painel de tarefas Controlos, em Entrada, clique em Caixa de Texto.
    • InfoPath 2007: no painel de tarefas Controlos , em Padrão, clique em Caixa de Texto.
  6. Clique com o botão direito do rato no controlo Caixa de Texto e, em seguida, clique em Propriedades da Caixa de Texto.

  7. Na caixa de diálogo **Propriedades da Caixa de Texto **, escreva o NomeDoAttachment na caixa **Nome do Campo **e, em seguida, clique em OK.

  8. Adicione um botão Anexar ao formulário do InfoPath ao utilizar as instruções para a versão do InfoPath que está a utilizar:

    • InfoPath 2010: no painel de tarefas Controlos , em Objetos, clique em Botão.
    • InfoPath 2007: no painel de tarefas Controlos , em Padrão, clique em Botão.
  9. Clique com o botão direito do rato no novo controlo de Botão e, em seguida, clique em Propriedades do Botão.

  10. Na caixa de diálogo **Propriedades do Botão **, escreva Anexar na caixa **Etiqueta **, escreva btnAttach na caixa ID e, em seguida, clique em Editar Código de Formulário.

  11. Desloque-se para a parte superior da janela do código e, em seguida, adicione a seguinte linha de código:

    using InfoPathAttachmentEncoding;
    
  12. Volte a "escrever o seu código aqui" e, em seguida, adicione o seguinte código:

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

Adicionar um botão Guardar ao formulário do InfoPath

  1. Voltar ao modelo de formulário do InfoPathAttachmentEncoding.

  2. Adicione um botão Guardar ao utilizar as instruções para a versão do InfoPath que está a utilizar:

    • InfoPath 2010: no painel de tarefas Controlos , em Objetos, clique em Botão.
    • InfoPath 2007: no painel de tarefas Controlos , em Padrão, clique em Botão.
  3. Clique com o botão direito do rato no novo controlo de Botão e, em seguida, clique em Propriedades do Botão.

  4. Na caixa de diálogo **Propriedades do Botão **, escreva Guardar na caixa **Etiqueta **, escreva btnSave na caixa **ID **e, em seguida, clique em Editar Código de Formulário.

  5. Insira o seguinte código:

     //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");
     }                                              
    
    

Nota

Neste código, o caminho do espaço para a pasta para guardar os anexos apresenta a localização na qual pretende guardar o ficheiro.

Clique no ícone Guardar e, em seguida, feche o VSTA.

Testar o formulário

Antes de este formulário poder anexar um ficheiro, o modelo de formulário do InfoPath tem de ser totalmente fiável. Para se certificar disto, eis uma das seguintes ações:

  • Utilize um certificado de assinatura de código para assinar digitalmente o ficheiro de modelo de formulário (.xsn). Quando o fizer, será pedido aos utilizadores que confiem no formulário quando abrirem o formulário. Isto torna o formulário totalmente fiável. Portanto, as permissões de Confiança Total são concedidas ao seu código Visual C#.
  • Criar um modelo instalável.

Depois de se certificar de que o modelo de formulário é totalmente fiável, deve testá-lo. Para tal, siga estes passos:

  1. Abra o formulário no modo de Pré-visualização ao seguir os passos para a versão do InfoPath que está a utilizar:

    • InfoPath 2010 No separador Home , clique em Preview.
    • InfoPath 2007 Na Barra de ferramentas Padrão, clique em Pré-visualizar.
  2. No formulário do InfoPath, escreva o caminho do ficheiro que pretende anexar na caixa de texto e, em seguida, clique em Anexar.

    Nota Faça duplo clique no controlo Anexo de Ficheiro para verificar se o ficheiro está codificado corretamente. 

  3. Clique em Guardar.

  4. Localize o caminho que forneceu no código para a secção "Adicionar um botão Guardar ao formulário do InfoPath" e, em seguida, certifique-se de que o ficheiro foi guardado nessa pasta. 

  5. Clique em Fechar Pré-visualização. Esta ação termina o teste.