InfoPath 2010 또는 InfoPath 2007에서 Visual C#을 사용하여 프로그래밍 방식으로 파일 첨부 파일을 인코딩하고 디코딩하는 방법

요약

Microsoft InfoPath 2010 또는 Microsoft Office InfoPath 2007에서 파일 첨부 파일 컨트롤을 사용하여 InfoPath 양식 서식 파일에 파일을 첨부할 수 있습니다. 특정 상황에서는 파일 첨부 파일 컨트롤에 연결된 파일을 인코딩한 다음 디코딩할 수 있습니다. 이 경우 Microsoft Visual C#을 사용하여 인코더 클래스 및 Decoderclass를 만들 수 있습니다. 그런 다음, 인코더 클래스와 Decoderclass를 사용하여 파일 첨부 파일을 인코딩하고 디코딩할 수 있습니다. 이 문서에서는 양식에 첨부할 파일을 인코딩하고 파일 시스템에 저장하기 위해 첨부 파일을 디코딩하는 InfoPath 양식 서식 파일을 디자인하는 방법을 설명합니다.  

InfoPath 2003에서 이 작업을 수행하는 방법에 대한 자세한 내용은 다음 문서 번호를 클릭하여 Microsoft 기술 자료의 문서를 봅니다.

892730 InfoPath에서 Visual C#을 사용하여 프로그래밍 방식으로 파일 첨부 파일을 인코딩 및 디코딩하는 방법

추가 정보

Microsoft는 특정 목적에 대한 상업성 및/또는 적합성에 대한 암시적 보증을 포함하되 이에 국한되지 않는 명시적 또는 묵시적 보증 없이 실례에 대한 프로그래밍 예제를 제공합니다. 이 문서의 내용은 프로시저를 작성하고 디버깅하는 데 사용되는 도구 및 여기에서 설명하는 프로그래밍 언어에 익숙한 사용자를 대상으로 합니다. Microsoft 지원 엔지니어는 사용자에게 도움이 되도록 특정 프로시저에 대한 기능을 설명할 수 있지만 사용자의 특정 요구 사항에 맞도록 예제를 수정하여 추가 기능을 제공하거나 프로시저를 구성하지는 않습니다.

다음 예제에서는 다음 단계를 수행합니다.

  1. Visual C# 프로젝트를 포함하는 양식을 만듭니다.
  2. 인코더 클래스를 만듭니다.
  3. Decoderclass를 만듭니다.
  4. 코드를 호출하도록 양식을 수정합니다.
  5. 양식에서 코드 작업을 테스트합니다.

Visual C# 프로젝트를 포함하는 양식 만들기

사용 중인 InfoPath 버전에 대한 지침을 사용하여 양식 서식 파일 및 프로젝트를 만듭니다.

InfoPath 2010

  1. InfoPath 디자이너에서 빈 양식 서식 파일을 만든 다음 저장 아이콘을 클릭합니다.
  2. 메시지가 표시되면 파일 이름을 입력하고 저장을 클릭합니다.
  3. **개발자 **탭을 클릭한 다음 언어를 클릭합니다.
  4. 양식 서식 파일 코드 언어에서 C#을 선택한 다음 확인을 클릭합니다.

InfoPath 2007

  1. **파일 **메뉴에서 양식 서식 파일 디자인을 클릭합니다.
  2. **양식 서식 파일 디자인 **작업창에서 공백 을 클릭한 다음 확인을 클릭합니다.
  3. 파일 메뉴에서 저장을 클릭합니다.
  4. 메시지가 표시되면 파일 이름 InfoPathAttachmentEncoding을 입력하고 저장을 클릭합니다.
  5. 도구 메뉴에서 양식 옵션을 클릭합니다.
  6. **양식 옵션 **대화 상자의 범주 아래에서 프로그래밍을 클릭합니다.
  7. 프로그래밍 언어 아래의 양식 서식 파일 코드 언어 목록에서 C#을 선택한 다음 확인을 클릭합니다.

인코더 클래스 만들기

사용 중인 InfoPath 버전에 대한 지침을 사용하여 인코더 클래스를 만듭니다.

InfoPath 2010

  1. 개발자 탭에서 **코드 편집기 **를 클릭하여 VSTA(Visual Studio Tools for Applications) 편집기를 시작합니다.
  2. 프로젝트 메뉴에서 새 항목 추가를 클릭합니다.
  3. 클래스를 선택하려면 클릭합니다.
  4. 이름 필드에서 이름을 InfoPathAttachmentEncoder.cs로 변경한 다음 저장을 클릭합니다.
  5. 코드 창에서 기존 코드를 다음 "인코더 코드" 섹션의 코드로 바꿉니다.

InfoPath 2007

  1. VSTA(Visual Studio Tools for Applications) 편집기를 시작합니다. 
  2. **프로젝트 탐색기 **창에서 InfoPathAttachmentEncoding을 마우스 오른쪽 단추로 클릭하고 추가를 클릭한 다음 새 항목을 클릭합니다.
  3. 템플릿 섹션에서 클래스를 선택하고 이름을 InfoPathAttachmentEncoder.cs로 변경한 다음 추가를 클릭합니다.
  4. 코드 창에서 다음 "인코더 코드" 섹션의 코드를 붙여넣습니다.

인코더 코드

InfoPath 2010 또는 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());
}
}
}

Decoder 클래스 만들기

사용 중인 InfoPath 버전에 대한 지침을 사용하여 Decoderclass를 만듭니다.

InfoPath 2010

  1. 코드 편집기에서 프로젝트 메뉴에서 새 항목 추가를 클릭한 다음 클릭하여 클래스를 선택합니다.
  2. 이름 필드에서 이름을 InfoPathAttachmentDecoder.cs로 변경한 다음 저장을 클릭합니다.
  3. 코드 창에서 기존 코드를 다음 "디코더 코드" 섹션의 코드로 바꿉니다. 

InfoPath 2007

  1. VSTA의 **프로젝트 탐색기 **창에서 InfoPathAttachmentEncoding을 마우스 오른쪽 단추로 클릭하고 추가를 클릭한 다음 새 항목을 클릭합니다.
  2. 템플릿 섹션에서 클래스를 선택하고 이름을 InfoPathAttachmentDecoder.cs로 변경한 다음 추가를 클릭합니다.
  3. 코드 창에서 다음 "디코더 코드" 섹션의 코드를 붙여넣습니다.

코드 디코더

InfoPath 2010 또는 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; }
}
}
}

양식 수정

InfoPath 양식에 파일 첨부 파일 컨트롤, 텍스트 상자 컨트롤 및 단추 컨트롤을 추가합니다. 이렇게 하려면 다음과 같이 하십시오.

  1. 사용 중인 InfoPath 버전에 대한 지침을 사용하여 컨트롤 작업창을 엽니다. 

    • InfoPath 2010:InfoPathAttachmentEncoding InfoPath 양식 서식 파일의 **홈 **탭 아래에서 **컨트롤 **갤러리를 확장합니다.
    • InfoPath 2007:InfoPathAttachmentEncoding InfoPath 양식 서식 파일에서 **디자인 작업 **작업 창에서 컨트롤 을 클릭합니다.
  2. 사용 중인 InfoPath 버전에 대한 지침을 사용하여 InfoPath 양식에 파일 첨부 파일 컨트롤을 추가합니다.

    • InfoPath 2010: 컨트롤 작업창의 개체 아래에서 파일 첨부 파일을 클릭합니다.
    • InfoPath 2007: 컨트롤 작업창의 파일 및 그림에서 파일 첨부 파일을 클릭합니다.
  3. **파일 첨부 파일 **컨트롤을 마우스 오른쪽 단추로 클릭한 다음 파일 첨부 파일 속성을 클릭합니다.

  4. **파일 첨부 파일 속성 **대화 상자에서 **필드 이름 **상자에AttachmentFieldin을 입력하고 확인을 클릭합니다.

  5. 사용 중인 InfoPath 버전에 대한 지침을 사용하여 InfoPath 양식에 Text Box 컨트롤을 추가합니다.

    • InfoPath 2010: 컨트롤 작업창의 입력에서 텍스트 상자를 클릭합니다.
    • InfoPath 2007: 컨트롤 작업창의 표준 아래에서 텍스트 상자를 클릭합니다.
  6. 텍스트 상자 컨트롤을 마우스 오른쪽 단추로 클릭한 다음 텍스트 상자 속성을 클릭합니다.

  7. **텍스트 상자 속성 **대화 상자의 **필드 이름 **상자에AttachmentName을 입력하고 확인을 클릭합니다.

  8. 사용 중인 InfoPath 버전에 대한 지침을 사용하여 InfoPath 양식에 연결 단추를 추가합니다.

    • InfoPath 2010: 컨트롤 작업창의 개체 아래에서 단추를 클릭합니다.
    • InfoPath 2007: 컨트롤 작업창의 표준 아래에서 단추를 클릭합니다.
  9. 새 단추 컨트롤을 마우스 오른쪽 단추로 클릭한 다음 단추 속성을 클릭합니다.

  10. **단추 속성 **대화 상자에서 **레이블 **상자에 첨부를 입력하고 ID 상자에 btnAttach를 입력한 다음 양식 코드 편집을 클릭합니다.

  11. 코드 창의 맨 위로 이동한 다음, 다음 코드 줄을 추가합니다.

    using InfoPathAttachmentEncoding;
    
  12. "여기서 코드 작성"으로 돌아가서 다음 코드를 추가합니다.

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

InfoPath 양식에 저장 단추 추가

  1. InfoPathAttachmentEncoding 양식 서식 파일로 돌아갑니다.

  2. 사용 중인 InfoPath 버전에 대한 지침을 사용하여 저장 단추를 추가합니다.

    • InfoPath 2010: 컨트롤 작업창의 개체 아래에서 단추를 클릭합니다.
    • InfoPath 2007: 컨트롤 작업창의 표준 아래에서 단추를 클릭합니다.
  3. 새 단추 컨트롤을 마우스 오른쪽 단추로 클릭한 다음 단추 속성을 클릭합니다.

  4. **단추 속성 **대화 상자에서 **레이블 **상자에 저장을 입력하고** ID **상자에 btnSave를 입력한 다음 양식 코드 편집을 클릭합니다.

  5. 다음 코드를 삽입합니다.

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

참고

이 코드에서 첨부 파일을 저장할 폴더의 자리 표시자 경로는 파일을 저장할 위치를 나타냅니다.

저장 아이콘을 클릭한 다음 VSTA를 닫습니다.

양식 테스트

이 양식에서 파일을 첨부하려면 InfoPath 양식 서식 파일을 완전히 신뢰할 수 있어야 합니다. 이를 확인하려면 다음 작업 중 하나를 수행합니다.

  • 코드 서명 인증서를 사용하여 양식 서식 파일(.xsn)에 디지털 서명합니다. 이렇게 하면 양식을 열 때 양식을 신뢰하라는 메시지가 사용자에게 표시됩니다. 이렇게 하면 폼을 완전히 신뢰할 수 있습니다. 따라서 Visual C# 코드에 완전 신뢰 권한이 부여됩니다.
  • 설치 가능한 템플릿을 만듭니다.

양식 서식 파일이 완전히 신뢰할 수 있는지 확인한 후 테스트해야 합니다. 이렇게 하려면 다음과 같이 하십시오.

  1. 사용 중인 InfoPath 버전에 대한 단계에 따라 미리 보기 모드에서 양식을 엽니다.

    • InfoPath 2010 탭에서 미리 보기를 클릭합니다.
    • InfoPath 2007 Standardtoolbar에서 미리 보기를 클릭합니다.
  2. InfoPath 양식에서 텍스트 상자에 첨부할 파일의 경로를 입력한 다음 첨부를 클릭합니다.

    참고 파일 첨부 파일 컨트롤을 두 번 클릭하여 파일이 올바르게 인코딩되었는지 확인합니다. 

  3. 저장을 클릭합니다.

  4. "InfoPath 양식에 저장 단추 추가" 섹션의 코드에서 제공한 경로를 찾은 다음 파일이 해당 폴더에 저장되었는지 확인합니다. 

  5. 미리 보기 닫기를 클릭합니다. 그러면 테스트가 종료됩니다.