Deploying InfoPath 2007 Forms to Forms Server – Properly!

Posted on 6/24/2009 @ 1:14 PM in #SharePoint by | Feedback | 16092 views

Okay so, the catchphrase/keyword here is “properly”. This begs the question, what is improper?

See in InfoPath 2007, if you read all the docs, books, and even MSDN, they ask you to craft an InfoPath form, and then go through the publishing steps. Specifically, the docs call you to publish “To a SharePoint Server with or without InfoPath Forms Services”.

Hmm .. that’s good except, developers don’t deploy – infrastructure guys do.

My new motto is “If I can’t deploy properly, the feature doesn’t exist”.

So I am glad to say, that deploying infopath 2007 forms to forms server as web based forms is a feature that does exist – i.e. – you CAN package them up as features and solutions, and deploy them like god intended mankind to.

Here is how you can create and publish such a form.

  1. Craft up your InfoPath Form – try and avoid certain features (too many to list here).
  2. Publish it to “a network location”. This is a file on your disk.
    1. Ensure that while publishing to a network location, when faced with this question “if all form users can access the location that you entered .. “, blank out the textbox – you do not want the information of “where the form lives”, to be embedded in the form – you want that information to be embedded in the feature.
  3. Great – now with the form published, craft up a visual studio solution, that will act as your InfoPath form/content type deployer.

Here is how you can craft up such a feature.

  1. Craft up a project structure like this (this is a class library) -
  2. In feature.xml, put in the following code -
  3.    1:  <?xml version="1.0" encoding="utf-8" ?>
       2:  <Feature xmlns="http://schemas.microsoft.com/sharepoint/"
       3:           Id="41CEE181-9440-4536-A1DA-73F41D2155B7"
       4:           Title="My Form"
       5:           Description="This feature deploys the browser enabled InfoPath Form."
       6:           Version="12.0.0.0"
       7:           Scope="Site"
       8:           DefaultResourceFile="ipfscore"
       9:           ReceiverClass="Microsoft.Office.InfoPath.Server.Administration.XsnFeatureReceiver"
      10:           ReceiverAssembly="Microsoft.Office.InfoPath.Server, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" >
      11:      <ActivationDependencies>
      12:          <ActivationDependency FeatureId="C88C4FF1-DBF5-4649-AD9F-C6C426EBCBF5"/>
      13:      </ActivationDependencies>
      14:      <ElementManifests>
      15:          <ElementManifest Location="element.xml"/>
      16:          <ElementFile Location="MyForm.xsn"/>
      17:      </ElementManifests>
      18:      <Properties>
      19:          <Property Key="FeatureName" Value="My InfoPath Form Template Feature"/>
      20:      </Properties>
      21:  </Feature>
    1. If you note, in the above, there is a receiver class that takes the responsibility of extracting the content type, and ensuring that the content type is browser renderable. How it does that? Heck I don’t know – the reflector code is obfuscated. I’m guessing it’s the equivalent of setting something in the database directly, which I shouldn’t be touching anyway. Except I know it works, and this is a supported mechanism because MSFT uses this all over the place.
    2. Secondly, if you note, There is an activation dependency. The dependency is ensuring that you have enterprise features turned on. That’s it.
  4. In the elements.xml put in the following code –
  5.    1:  <?xml version="1.0" encoding="utf-8" ?>
       2:  <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
       3:      <Module Name="XSN" Url="FormServerTemplates" RootWebOnly="TRUE">
       4:          <File Url="MyForm.xsn" Name="MyForm.xsn" Type="GhostableInLibrary"/>
       5:      </Module>
       6:  </Elements>
    1. As you can tell, I am simply copying over the MyForm.xsn over to a place called ~site/FormServerTemplates. If you view the SharePoint file system on the site (i.e. inside the content db), you will see that FormServerTemplates is a special place where templates for content types exist.
  6. Your Install.bat looks like this –
  7.    1:  @SET STSADM="c:\program files\common files\microsoft shared\web server extensions\12\bin\stsadm"
       2:  @SET GACUTIL="c:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\gacutil.exe"
       3:  @SET WSPPBUILDER="C:\Code\WspBuilder\WspBuilder.exe"
       4:   
       5:  @echo off
       6:  Echo Creating Solution Package
       7:  %WSPPBUILDER% -outputpath solution -Excludepaths bin
       8:   
       9:  Echo Retracting Solution
      10:  stsadm -o retractsolution -name MyForm.wsp -immediate
      11:  stsadm -o execadmsvcjobs
      12:   
      13:  Echo Deleting Solution
      14:  stsadm -o deletesolution -name MyForm.wsp
      15:   
      16:  Echo Adding Solution
      17:  stsadm -o addsolution -filename Solution\ MyForm.wsp
      18:   
      19:  Echo Deploying solution
      20:  stsadm -o deploysolution -name MyForm.wsp -immediate -allowGacDeployment -force
      21:  stsadm -o execadmsvcjobs
      22:   
      23:  Echo Resetting IIS
      24:  IISRESET
    1. As you can tell, I’m a fan of WSPBuilder. You should be too.
  8. Modify your project to call Install.bat at successful builds.
  9. That’s basically it. Build & Deploy.

How to use it?

  1. Create a Forms Library
  2. Go to its Settings à Advanced Settings. Choose to allow management of content types, and choose to open “Browser Enabled Documents” in Web Pages, rather than the Client Application.
  3. After having deployed the solution & activated the feature, you will see that there is a new content type called available called “MyForm”. Use that content type as the default content type of the document library you created above in Step #2.
  4. Delete the default “form” content type.
  5. That’s it – click “New” and the form should be running browser enabled. w00t!

How to deploy to production?

Simple – hand over the .wsp to your infrastructure guy, turn your phone off, and go have a smoke (or chew gum – whatever might be your thing).

Sound off but keep it civil:

Older comments..


On 8/21/2008 2:40:07 PM stephane eyskens said ..
Hi,

Good post!

Thanks for sharing it!


On 8/27/2008 1:39:57 PM TJ said ..
Much agreed, great post. I do however have one issue.

I have an InfoPath form which when deployed using a solution throws an error

"The XSN can not be used on server"

After searching I thought the problem was to do with the security settings. I removed existing data connections to SharePoint lists on another domain thinking that would fix the issue (cross domain being the problem). However the problem persists when deploying in a solution format. It is worth mentioning that although it is failing via a solution using the InfoPath publishing wizard works fine.


On 8/28/2008 9:52:16 AM TJ said ..
Answer to previous question. Read blogs properly and don't shortcut. Basically I hadn't published the form to a network location. Thanks.


On 9/11/2008 11:24:32 AM Christina Odom said ..
Excellent post. Have you done this with forms that are to be Content Types?


On 9/11/2008 7:02:09 PM Sahil Malik said ..
Christina - Yep it'll work!


On 9/12/2008 10:08:51 AM Lawrence said ..
Nice post, only thing is that for me it doesn't end up as a content type. I get the file into the FormServerTemplates-folder but it never shows in the content type dropdown. I have activated features and done everything acording to your instructions 4 times now but no luck. Any idea as to why it won't show?

Btw we're doin this on WinServ2008 with MOSS2007 SP1, VS08 SP1 and Office2007.


On 9/18/2008 12:36:46 PM Christina Odom said ..
So random question. From a maintainence standpoint, if this feature is part of a larger solution package (think site definitons, content types, etc), would just uploading the updated .xsn file to CA be enough (as with standard admin-approved forms?) or would you have to rebundle and upgrade the solution package every time?


On 9/19/2008 8:26:11 AM Sahil Malik said ..
Uploading won't be enough!


On 10/15/2008 4:50:50 AM Raul Queiroga said ..
Excelent post, it was what I was looking for. Now for another, imagine I want to create a list definition that uses the content type deployed in that feature. How do I set the ID of the fields in the view element of the schema.xml since I only know them after the form is deployed (the purpose is a solution package with both features)?


On 10/21/2008 7:25:31 PM Ashley Frank said ..
Christina, Uploading xsn and approving was enough for me to get the content type to show.


On 10/29/2008 5:13:14 PM RJ said ..
Unable to view the item for "Craft up a project structure like this (this is a class library) - " I am a newbie and would like learn how to create a solution.wsp file. Can you direct me to the right place?


On 11/10/2008 2:04:59 AM suja said ..
Hey great post!!


I was looking for exactly same thing to publish my 10+ infopath forms in various servers.


Now my problem is how to handle the code behind dlls for each form?


On 11/19/2008 2:02:54 PM Jonathan K. Herschel said ..
http://img170.imageshack.us/img170/7963/capturetb7.png seems to be missing. Can you fix?


thanks!


On 2/25/2009 1:32:53 PM Dan said ..
When you create the infopath form MyForm.xsn, the location of the data connection library is embedded. Your code is only changing what is in the udcx files, not where they are located. How do you handle this when you develop the MyForm.xsn on one site and deploy it to a different site?


On 3/9/2009 8:00:46 PM baicaicai said ..

On 3/14/2009 1:14:29 PM allen said ..
An important note here is that this post will only work if the InfoPath forms are deployed into the same directory as the feature.xml file. The feature receiver class referenced in it's FeatureInstalled() implementation only looks for XSN files in the features root directory.

If you place your XSN files into a seperate directory, then you will need to:


1. Add a custom property to your feature.xml that hints where the InfoPath forms are


deployed to. For example:


<Properties>


<Property Key="InfoPathFormsFeatureRelativeDirectory" Value="InfoPath\*.xsn"/>


</Properties>

2. Write and register your own/custom feature receiver.


+ In your feature receiver FeatureInstalled() implementation:


- Use the custom property to generate a list of fully qualified file names of your


InfoPath forms (see function EnumerateInfoPathFormTemplates below).


- Once you have the list of InfoPath forms, call Micosoft.Office.InfoPath.Server.Administration.FormTemplateCollection.RegisterFormTemplate function (located in Microsoft.Office.InfoPath.Server.dll) for each of your InfoPath forms to make them available on your SharePoint instance.


+ In your feature receiver FeatureUninstalled() implementation:


- Use the custom property to generate a list of fully qualified file names of your


InfoPath forms (see function EnumerateInfoPathFormTemplates below).


- Once you have the list of InfoPath forms, call Micosoft.Office.InfoPath.Server.Administration.FormService.FormTemplates.UnregisterFormTemplate function (located in Microsoft.Office.InfoPath.Server.dll) for each of your InfoPath forms to remove them from your SharePoint instance. To get an instance of the FormsService, do the following:

FormsService formsService = SPFarm.Local.Services.GetValue<FormsService>("");

Doing all this will make all your InfoPath forms available.

private static List<String> EnumerateInfoPathFormTemplates(SPFeatureDefinition featureDefinition)


{


SPFeatureProperty property =


featureDefinition.Properties[PreRegistrationInfoPathFormsReceiver.InfoPathFormsFeatureRelativeDirectory];

if ((property == null) || (String.IsNullOrEmpty(property.Value)))


{


throw new ArgumentException("Invalid InfoPath forms location specified.");


}

FileInfo[] infoPathFileInfos =


new DirectoryInfo(featureDefinition.RootDirectory).GetFiles(property.Value);

List<String> infoPathFormFileSpecs = new List<String>();

foreach (FileInfo fi in infoPathFileInfos)


{


infoPathFormFileSpecs.Add(Path.Combine(fi.DirectoryName, fi.Name));


}

return infoPathFormFileSpecs;


}


On 3/26/2009 12:08:35 PM Dan said ..
Allen,


Do you have an example of the custom event receiver to do what you suggest? I'm new at this and am getting confused, as the feature as defined above already has a receiverassemble and class, so I'm not sure how to include an additional custom event receiver. thanks Dan


On 3/26/2009 12:09:19 PM Dan said ..
Allen,


Do you have an example of the custom event receiver to do what you suggest? I'm new at this and am getting confused, as the feature as defined above already has a receiverassemble and class, so I'm not sure how to include an additional custom event receiver. thanks Dan


On 4/6/2009 2:25:22 PM Claudia said ..
Hello, I've create a feature that deploys aroung 5 InfoPath forms. I'd like to know if there is workaround for the uploading issue. I get an error if I try to upload a new version: The following form template cannot be upgraded because it is not currently uploaded on this farm

So? Do I need to uninstall the feature and install it again or there is a better way?

Thanks


On 4/29/2009 5:30:07 AM troy said ..

On 6/16/2009 2:49:01 PM Bob said ..
YO!!!! Somebody PLEASE put up an image or get rid of it and put up a proper text entry to show the structure that's to be created!!!!!


On 6/16/2009 3:26:49 PM Sahil Malik said ..
Bob - sorry for that.


The image - well Imageshack deletes crap without warnings - can't complain because it's free :)

Anyway, the struct is like this .. (hopefully indentation doesnt screw it up)

Your Sol -


12


Template


Features


YourFeature


- Feature.XML


XSN


-YourInfoPathForm.XSN

:)

S


On 6/16/2009 3:27:27 PM Sahil Malik said ..
<pre>


Your Sol -


12


Template


Features


YourFeature


- Feature.XML


XSN


-YourInfoPathForm.XSN

</pre>

Trying again!


On 6/16/2009 3:27:34 PM Sahil Malik said ..
<pre>


Your Sol -


12


Template


Features


YourFeature


- Feature.XML


XSN


-YourInfoPathForm.XSN

</pre>

Trying again!


On 7/8/2009 1:27:09 PM Andrew said ..
Very helpful post. Thanks for taking the time to write it up in so much detail.


I had small problem I had to overcome, which I thought others might benefit from.

Make sure your InfoPath form has a version assigned, or else on activation you will get an error thrown within the method Microsoft.Office.InfoPath.Server.Administration.FormTemplate.GetLatestVersion()

Find this under Tools | Form Options | Versioning


On 7/14/2009 2:29:02 AM Mario said ..
Thanks for the great post.


Please would you write a note on upgrading the form through a wsp. I have wrapped my forms in a solution an deployed it as you described. Through the "Upload form template" dialog and the stsadm it is possible to quiesce the old template and upgrade it with the new one. My problem: I have a doc lib filled with xmls of the old template. When I deactivate, retract and redeploy my feature with the new xsn, the old xmls cannnot be opened.

Thanks for your help.


On 9/5/2009 5:33:06 AM Mehul Bhuva said ..
Hi Sahil,

I like your articles, they are really descriptive and informative. Keep up the good work.


Well I have a question in relation to the above post, suppose I have already deployed the above created wsp, installed and activated the feature, added the content type to my document library that hosts my infopath form. Everything works great.

Now, I have updated the Infopath form to add/remove certain fields and recreate the wsp with the new changes, what are the options I have to redeploy the newly created Infopath template to my sharepoint environment.

I have tried upgrade wsp, it fails sometimes, does not give results consistently, when I try to remove the content type from the doc lib and then deactivate, uninstall the feature, remove the solution and redeploy using the steps mentioned, then re-add the updated content type, my list columns get duplicated with the earlier columns still in place. How do i fix this up? Would be greatfull, if u can help


On 10/15/2009 9:29:49 PM Don G. said ..
I have successfully add / deployed the wsp file with the form & code behind dll. Howver, when I try to activate the feature at site collection level I see "Failig FormTemplate.GetLatestVersion" in log file. In addition I see status="Installing" in central administration->application management->Manage Form Template. I have checked the versioning, and its 1.0.0.4, with version upgrade set to "Automatically Upgrade Existng Form". Can any one please tell me why am I getting exception when I try to activate the feature?? Would really appreciate any input..thanks.


On 12/18/2009 9:24:09 AM Mehul Bhuva said ..
Hi Sahil,

I am a big big fan of your posts, I do blog too..

See my blog post where I take you step-by-step with relevant snapshots covering the following:


a. Converting InfoPath Data Connections to DCL library in SharePoint.


b. Publishing InfoPath form to a SharePoint List/Library


c. Creating a .wsp solution package for the InfoPath form and its code-behind


d. Creating a batch script that will deploy the InfoPath form on your Production site.


e. Ensuring the InfoPath form has been deployed as a feature


f. Modify the DCL’s in the production environment.


g. Associate the InfoPath Content Type with the Document/Forms Library

See the full blog post at: http://www.sharepointfix.com/2009/12/infopath-2007-form-and-nintex-workflows.html


On 1/6/2010 3:41:04 PM Tanya said ..
I have a manage code in my InfoPath form .


I followed the steps ,after deploying I can see feature and infopath template inside "Form Templates" list.


Everything is activated but once I am trying to preview this form in browser it give me an error "Form has been close".

I understand that based on this deployment there is no need to upload templates with manage code for admin approval. Is it right?

What did I do wrong? Form is working once going with manual steps of upload


Should form be published to network or browser enable to SharePoint?

Thanks


On 3/29/2010 4:55:33 PM Igr Alexánder Fernández Saúco. said ..
I try to use VSeWSS 1.3 CTP instead WSPBuilder. The resulting package structure from the package process do no put the feature.xml on the same directory of "*.xsn" files.

I implemented my own custom xsn feature receiver, activating and making avaliable the form on the sites where the feature is activated. But the from do not display as "Content Type".

So, I can't assign the registered infopath form as content type of any library.

Any ideas,


Thanks in advanced.


On 10/26/2010 9:48:07 AM Steve said ..
Hi Sahil,

I've deployed dozens of forms using this solution\feature approach and it worked fine with MOSS2007, but now we've started upgrading to 2010 and the retracting process seems to be failing. Have you tried this on 2010? Deploying the forms seems to work, but retracting and redeploying it later doesn't - at least not for me.

When I have an updated form I use the upgradesolution command and then I would retract the solution and then immediately deploy it again. That seemed like the only way to get the updated form uploaded into the formservertemplates folder.

Now that we're on 2010 I upgrade the solution, retract the form, but when I try to deploy it again I get an error:

"An object of the type Microsoft.Office.InfoPath.Server.Administration.FormTemplate named "urn:schemas-microsoft-com:office:infopath:FormNameHere:-myXSD-2009-06-19T17-58-09" already exists under the parent Microsoft.SharePoint.Administration.SPFarm named "SharePoint_Config". Rename your object or delete the existing object."

Seems like there are a few entries in the config database that aren't getting removed when the feature is deactivated.

Any ideas? Thanks.


On 10/26/2010 11:35:39 AM Steve said ..
Answer to my previous post:

I sorted out the SharePoint 2010 retracting issue - it was just a matter of changing the feature definition file and specifying Version=14.0.0.0 instead of Version=12.0.0.0

Once I made that change the solution could be retracted and re-deployed in 2010.

Thanks.


On 11/17/2010 7:01:59 PM Thiago said ..
Hi There,

I faced the same problem as Tanya. I'm following all the steps, and I'm using a very simple InfoPath Form, just to test. It creates the feature, it uploads the form to Form Service, it creates the content type, and it even open using a client application. But when I try to use browser enabled, it crashes and shows the error "The form has been closed.". Any guess?

Thank you.


On 2/24/2011 5:34:11 AM surendra said ..
I tried to publish a form directly from infopath 2010 to sharepoint 2010 .It was succeeded.But the problem is after filling the form with infopath form filler it is stored in local memory.But it should be done in sharepoint library?


Any ideat about this?


Thanking you


On 3/4/2011 3:46:22 PM Ani said ..
Can we use the same method for deploying InfoPath form as Sandbox solution in SP2010?


If not can you give me some pointers/help how we can?

thanks in advance

Regards


Ani


On 7/21/2011 1:55:18 AM Mukesh Bhavnani said ..
Great Post....


Thnx.... :)


On 8/31/2011 10:17:18 AM David said ..
Does publishing the InfoPath form as feature work with forms that have C# code behind?


On 8/31/2011 2:21:49 PM Sahil Malik said ..
Yes it does.


On 10/13/2011 8:14:13 AM David said ..
How does this effect versioning of the forms? In the batch file above, it removes the old file from Form Library. All the data that was entered in the old forms is then lost? Is there a place where versioning of InfoPath form is described? Thanks!


On 1/12/2012 2:18:46 PM Chris Wininger said ..
How do you get promoted fields to allow editing under a list items edit properties (EditForm.aspx)? Normaly this is an option you check in infopath when publishing to a list. The option is not available when you publish to a network path. I tried setting all the fields in list to ShowInEdit form durring the featur activation, but that still did nothing for the promoted columns.


On 3/20/2012 7:03:56 PM Allan said ..
Regarding the InfoPath form, I am having issues with Submit Actions. Is there supposed to be a submit action on the IPForm or does it simply use the Save button on the toolbar? I am having some issues getting my form to save the .xml in the library I have designated in my Submit Action.


On 9/5/2012 1:22:32 AM Nishant said ..
The project structure image seems to be missing from your article.


On 3/14/2013 1:28:05 AM Manvir said ..
I performed the same steps to make it work on sharepoint 2010. I dont get any error. But, I dont see any custom content type got created which I can apply on Forms library. Can you please help here?