Programmatically create InfoPath form using CSOM SharePoint 2010

The blog posts below describe how to create InfoPath form instance using server side code and the class InfopathFormGrocker
http://platinumdogs.me/2010/09/02/sharepoint-programmatically-creating-infopath-form-instance-documents-part-2-of-2/
http://platinumdogs.me/2010/07/28/sharepoint-programmatically-creating-infopath-form-instance-documents-1-of-2/

To use CSOM the application has to be modified as follows

1. Add the following assemblies
Microsoft.SharePoint.Client.dll
Microsoft.SharePoint.Runtime.dll

2. Get the InfoPath file from the content type

var clientContext = new ClientContext(siteUrl);
var list = clientContext.Web.Lists.GetByTitle(listName);

//get list level content type using ContentTypeExtensions
var listContentType = clientContext.Web.Lists.GetByTitle(listName).ContentTypes.GetByName(listContentTypeName);
var fileInfo = Microsoft.SharePoint.Client.File.OpenBinaryDirect(clientContext, listContentType.DocumentTemplateUrl);

In the above example ContentTypeExtensions has been used to be able to get content type by name. More information can be found at
http://sharepoint.stackexchange.com/questions/115499/get-a-content-type-by-name-title-using-csom

3. Using InfopathFormGrocker, the manifest.xsf and template.xml need to be extracted after converting the fileInfo object into memorystream

// get the Manifest xsf file
var memoryManifest = new MemoryStream();

byte[] bufferManifest = new byte[1024 * 64];
int nreadManifest = 0;
while ((nreadManifest = fileInfo.Stream.Read(bufferManifest, 0, bufferManifest.Length)) > 0)
{
memoryManifest.Write(bufferManifest, 0, nreadManifest);
}

xsnForm.ExtractComponent(memoryManifest, "manifest.xsf");
XmlDocument formManifest = xsnForm.ComponentContent;

//memory is closed explaining why it is reinitialised
fileInfo = Microsoft.SharePoint.Client.File.OpenBinaryDirect(clientContext, listContentType.DocumentTemplateUrl);

// get the template Xml file

var memoryTemplate = new MemoryStream();

byte[] buffer = new byte[1024 * 64];
int nread = 0;
while ((nread = fileInfo.Stream.Read(buffer, 0, buffer.Length)) > 0)
{
memoryTemplate.Write(buffer, 0, nread);
}
xsnForm.ExtractComponent(memoryTemplate, "template.xml");
XmlDocument xsnFormTemplate = xsnForm.ComponentContent;

// get form metadata values
XmlNamespaceManager NamespaceManager = CreateNamespaceManager(formManifest);
string Name = formManifest.DocumentElement.GetAttribute("name", "");
string SolutionVersion = formManifest.DocumentElement.GetAttribute("solutionVersion", "");
string ProductVersion = formManifest.DocumentElement.GetAttribute("productVersion", "");

string HRef = listContentType.DocumentTemplateUrl;

XmlDocument formXML = CreateFormInstanceDocument(xsnFormTemplate.OuterXml, Name, SolutionVersion, ProductVersion, HRef);
//Manipulate the XMLDocument , e.g. update field properties
.......................................................

4. Use CSOM to upload the InfoPath to the library after converting the XmlDocument into MemoryStream


var formBytes = Encoding.UTF8.GetBytes(formXML.OuterXml);

MemoryStream xmlStream = new MemoryStream(formBytes);

clientContext.Load(list.RootFolder);
clientContext.ExecuteQuery();

var fileUrl = String.Format("{0}/{1}", list.RootFolder.ServerRelativeUrl, string.Format("Test creating InfoPath{0}.xml", DateTime.Now.ToString("yyyyMMddHHmmss")));

Microsoft.SharePoint.Client.File.SaveBinaryDirect(clientContext, fileUrl, xmlStream, true);

The code has been tested against SharePoint 2010. Might require some amendments to make it work for other versions of SharePoint