Wednesday, September 01, 2004

InfoPath Fun

Just finished a proof of concept with InfoPath. What we wanted was an automated way to convert a completed InfoPath form to TIFF in order to archive it in a document imaging system. Turns out it's possible, but a bit painful.

The first step is to write code in the form to capture it. That can be done by "signing" the form. When designing it, you can specify which pieces of data should be signed. For signing to work, the form must be Fully Trusted. See the InfoPath SDK for more info on fully trusted forms. Once that's done, I can capture the form in the OnSign event like so:
// The OnSign handler can be customized only in fully trusted form templates.
var Signature = eventObj.SignedDataBlock.Signatures.Create();
var PngNode = Signature.SignatureBlockXmlNode.selectSingleNode(".//sp:ScreenDumpPNG");

var fso = new ActiveXObject("Scripting.FileSystemObject");
var a = fso.CreateTextFile("c:\\TestFormPNG.txt", true);
a.Write(PngNode.text);
a.Close();

eventObj.ReturnStatus = true;
}


As you can see, the form is being captured and saved as a Base64-encoded PNG file. In my test, I fire this event by using a button that when clicked runs this line of code:
XDocument.SignedDataBlocks(0).Sign();


Once the Base64-encoded PNG file is saved, we can use System.Drawing.Imaging to grab that PNG and convert it to TIFF. Of course, it needs to be decoded to binary first. I wrote a little VB.NET Windows app that does this. Here's what it looks like:
Dim inFile As System.IO.StreamReader
Dim base64String As String

Try
Dim base64CharArray() As Char
inFile = New System.IO.StreamReader("C:\TestFormPNG.png", _
System.Text.Encoding.ASCII)
base64CharArray = New Char(inFile.BaseStream.Length) {}
inFile.Read(base64CharArray, 0, inFile.BaseStream.Length)
base64String = New String(base64CharArray, _
0, _
base64CharArray.Length - 1)
Catch exp As System.Exception
' Error creating stream or reading from it.
System.Console.WriteLine("{0}", exp.Message)
Return
End Try

' Convert the Base64 UUEncoded input into binary output.
Dim binaryData() As Byte
Try
binaryData = System.Convert.FromBase64String(base64String)
Catch exp As System.ArgumentNullException
System.Console.WriteLine("Base 64 string is null.")
Return
Catch exp As System.FormatException
System.Console.WriteLine("Base 64 length is not 4 or is " + _
"not an even multiple of 4.")
Return
End Try

'Write out the decoded data.
Dim outStream As New MemoryStream(binaryData)

Dim outImage As New Bitmap(outStream)

Dim TIFImage As Image = outImage
TIFImage.Save("c:\TestFormTIF.tiff", System.Drawing.Imaging.ImageFormat.Tiff)

MessageBox.Show("Image has been converted")


Now that my little test is working, I at least know it can be done. Now the real test will be to use this concept in real-world forms. I'll get that chance starting tomorrow when I begin a new project.

1 comment:

Anonymous said...

I am new to C#, and I was wondering if you could convert the VB.NET to C#?