Skip to Content

Publishing InfoPath 2010 forms from Visual Studio

Here is the code to realy be able to deploy forms from VS. If your form uses promoted properties, SPS will create contentypes with the properties as fields. Unfort. it will give these fields a guid as internalname. This might not be a problem, but if you need to uses these fields in code or other forms, thses guids will be different in Test or Production environments. If this is an issue, please create the contenttypes and the fields through elements

The code:

public static void PublishForm(SPFeatureReceiverProperties properties, string relativeFilePath, string formId)
{
try
{
FormsService localFormsService;
SPFarm localFarm = SPFarm.Local;

localFormsService = localFarm.Services.GetValue(FormsService.ServiceName);
//TODO get path from properties
string _filename = string.Format("{0}\\{1}", properties.Definition.RootDirectory, relativeFilePath.EndsWith(".xsn") ? relativeFilePath : string.Format("{0}.xsn", relativeFilePath));
if (localFormsService.FormTemplates[formId] == null)
{
// Adding form
try
{
ULSPublisher.WriteTrace(string.Format("Uploading InfoPath form with id [ {0} ].", formId));
localFormsService.FormTemplates.UploadFormTemplate(_filename);
WaitForTimerJobToFinish(localFormsService, formId);
ULSPublisher.WriteTrace(string.Format("Upload InfoPath form with id [ {0} ] succesfully completed.", formId));
}
catch (Exception ex)
{
ULSPublisher.WriteError(string.Format("FAILED: Uploading InfoPath form with id [ {0} ] failed with message: {1}.", formId, ex.Message));
}

// activating form
try
{
//using (SPSite site = properties.Feature.Parent as SPSite)
using (SPSite site = properties.Feature.Parent as SPSite == null ? (properties.Feature.Parent as SPWeb).Site : properties.Feature.Parent as SPSite)
{
if (site != null)
{
ULSPublisher.WriteTrace(string.Format("Activating InfoPath form with id [ {0} ] on web [ {1} ].", formId, site.Url));
localFormsService.FormTemplates[formId].Activate(site);
WaitForTimerJobToFinish(localFormsService, formId);
ULSPublisher.WriteTrace(string.Format("Activate InfoPath form with id [ {0} ] on web [ {1} ] succesfully completed.", formId, site.Url));

}
}
}
catch (Exception ex)
{
ULSPublisher.WriteError(string.Format("FAILED: Activating InfoPath form with id [ {0} ] failed with message: {1}.", formId, ex.Message));
}
}
else
{
try
{
// upgrading form
ULSPublisher.WriteTrace(string.Format("Upgrading InfoPath form with id [ {0} ].", formId));
localFormsService.FormTemplates.UpgradeFormTemplate(_filename, FormTemplateCollection.UpgradeType.OverwriteNoVersionCheck);
WaitForTimerJobToFinish(localFormsService, formId);
ULSPublisher.WriteTrace(string.Format("Upgrading InfoPath form with id [ {0} ] succesfully completed.", formId));
}
catch (Exception ex)
{
ULSPublisher.WriteError(string.Format("FAILED: Upgrade InfoPath form with id [ {0} ] failed with message: {1}.", formId, ex.Message));
}
// re-activating form
try
{
using (SPSite site = properties.Feature.Parent as SPSite == null ? (properties.Feature.Parent as SPWeb).Site : properties.Feature.Parent as SPSite)
{
if (site != null)
{
ULSPublisher.WriteTrace(string.Format("Activating InfoPath form with id [ {0} ] on web [ {1} ].", formId, site.Url));
localFormsService.FormTemplates[formId].Activate(site);
WaitForTimerJobToFinish(localFormsService, formId);
ULSPublisher.WriteTrace(string.Format("Activate InfoPath form with id [ {0} ] on web [ {1} ] succesfully completed.", formId, site.Url));

}
}
}
catch (Exception ex)
{
ULSPublisher.WriteError(string.Format("FAILED: Activating InfoPath form with id [ {0} ] failed with message: {1}.", formId, ex.Message));
}
}
}
catch (Exception ex)
{
ULSPublisher.WriteError(string.Format("FAILED: Publish or Upgrade InfoPath form with id [ {0} ] failed with message: {1}.", formId, ex.Message));
}

}

private static void WaitForTimerJobToFinish(FormsService localFormsService, string formId)
{
Stopwatch _stop = new Stopwatch();
try
{
_stop.Start();

while (localFormsService.FormTemplates[formId].FormTemplateStatus != FormTemplate.FormTemplateState.Normal)
{

if (_stop.ElapsedMilliseconds > 120000) throw new TimeoutException("Uploading Infopath forms timed out.");

}
}
catch (Exception ex)
{
ULSPublisher.WriteError(string.Format("Failed to wait for timer job to finish for formId [{0}] with message:\r{1}", formId, ex.Message));
}
finally
{
if (_stop != null && _stop.IsRunning) _stop.Stop();// always stop this timer
}
}

///
/// This method is responsible to delete the form in the CA and deactivate on the site where this feature resides.
///
/// The properties of the feature.
/// The form id (ie. urn:schemas-microsoft-com:office:infopath:{FORMNAME}:-myXSD-{CREATION TIMESTAMP}).
/// This can be found in design mode of the InfoPath form by File\Form Template Properties (on the right on the File tab)
///
public static void DeleteForm(SPFeatureReceiverProperties properties, string formId)
{
FormsService localFormsService;
SPFarm localFarm = SPFarm.Local;

localFormsService = localFarm.Services.GetValue(FormsService.ServiceName);

if (localFormsService.FormTemplates[formId] != null)
{
// deactivate form from site
try
{
using (SPSite site = properties.Feature.Parent as SPSite == null ? (properties.Feature.Parent as SPWeb).Site : properties.Feature.Parent as SPSite)
{
if (site != null)
{
ULSPublisher.WriteTrace(string.Format("Deactivating InfoPath form with id [ {0} ] on web [ {1} ].", formId, site.Url));
localFormsService.FormTemplates[formId].Deactivate(site);
ULSPublisher.WriteTrace(string.Format("Deactivate InfoPath form with id [ {0} ] succesfully completed.", formId));
}
}
}
catch (Exception ex)
{
ULSPublisher.WriteError(string.Format("Deactivation of InfoPath form with id [ {0} ] failed with message: {1}.", formId, ex.Message));
}

// delete form from CA
try
{
ULSPublisher.WriteTrace(string.Format("Deleting InfoPath form with id [ {0} ].", formId));
localFormsService.FormTemplates[formId].Delete();
ULSPublisher.WriteTrace(string.Format("Delete InfoPath form with id [ {0} ] succesfully completed.", formId));
}
catch (Exception ex)
{
ULSPublisher.WriteError(string.Format("Deletion of InfoPath form with id [ {0} ] failed with message: {1}.", formId, ex.Message));
}
}

}