Thursday, November 25, 2010

Publish Nintex workflow file to all sites and libraries using code

Nintex workflows - They are easy to build workflows and customize. I used them in couple of projects and it supports many activities which we can use and build workflows according to requirements. But, this time I got a big project which has plenty of sub sites in a site collection. All sub sites are having the same site template and it has the same structure. Each sub sites has many libraries and out of them 8 are having workflow enabled.
When I got a requirement to change something in workflow then I am in trouble like how to publish the new changed workflow to all libraries. Right now I have 148 sub sites. It means I have to publish the nintex workflow to 148 * 8  = 1184 libraries. Which is not at all possible with the manual upload process. So, the only way would be writing code to publish them automatically by running it.

Few days back, I have written the post which describes the same without coding here.  But, that needs lots of prerequisites and will apply to only one site. The solution which I have written needs the updated nintex workflow file [.NWF] as input, web url and site url. It loops through all sites in the site collection and updates the each and every library with the updated nintex file successfully.

Below is the code which does that for one site:
private static void UpdateWokflowToOneSite()
{
    string siteUrl = ConfigurationManager.AppSettings["SiteUrl"];
    List<string> listNames = new List<string>() { "List - 1", "List - 2", "List - 3", "List - 4", "List - 5"};
    using (SPSite site = new SPSite(siteUrl))
    {
        string webUrl = ConfigurationManager.AppSettings["WebUrl"];

        if (string.IsNullOrEmpty(webUrl))
        {
            webUrl = "/";
        }
        using (SPWeb web = site.OpenWeb(webUrl))
        {
            byte[] rawData = File.ReadAllBytes("UpdatedNintexWorkflow.nwf");
            NintexWorkflowWS.NintexWorkflowWS ws = new NintexWorkflowWS.NintexWorkflowWS();
            ws.Url = web.Url + "/_vti_bin/NintexWorkflow/workflow.asmx";
            ws.UseDefaultCredentials = true;

            int i = 1;
            foreach (string listName in listNames)
            {
                ws.PublishFromNWF(rawData, listName, string.Format("NintexWorkflow-{0}", i), false);
                i++;
            }
        }
    }
}        

Below are the prerequisites for running above code.
  1. I have created a console application and writing code in it. So that I will get EXE as output and running it wherever needed [different servers by changing configuration file]. 
  2. We have to add the Nintex workflow web service reference to the project. So that we will call it and use it in code. The below line in the code is web service instantiation.
    NintexWorkflowWS.NintexWorkflowWS ws = new NintexWorkflowWS.NintexWorkflowWS();
    
  3.  The user who is logged in has the permissions needed to publish the nintex workflow. The administrator access are needed to run the above code.
  4. The NWF file location according to above code should be in the same location where EXE is present. By default it will be project location/bin/debug.
  5.  listNames is the variable which has all list/library names in the site to which we have to publish the workflow. In case if you want to publish to all list/libraries then replace the listNames in foreach with web.Lists.
Now, the app.config entries are configurable. Below are the configuration changes needed.
<appSettings>
    <add key="SiteUrl" value="http://sharepointsite"/>
    <add key="WebUrl" value="/"/>
  </appSettings>
    <system.serviceModel>
        <bindings />
        <client />
    </system.serviceModel>
    <applicationSettings>
        <DeployWorkflowNWF.Properties.Settings>
            <setting name="DeployWorkflowNWF_NintexWorkflowWS_NintexWorkflowWS"
                serializeAs="String">
                <value>http://sharepointsite/_vti_bin/NintexWorkflow/Workflow.asmx</value>
            </setting>
        </DeployWorkflowNWF.Properties.Settings>
    </applicationSettings>
In this, change the configuration as needed and use it.

You can use the same code loop through each and every web and publish it to all webs. I mean one more loop is enough to do that job as shown below.
private static void UpdateWokflowToAllWebs()
{
    string siteUrl = ConfigurationManager.AppSettings["SiteUrl"];
    List<string> listNames = new List<string>() { "List - 1", "List - 2", "List - 3", "List - 4", "List - 5"};
    using (SPSite site = new SPSite(siteUrl))
    {
        foreach(SPWeb web in site.AllWebs)
        {
            byte[] rawData = File.ReadAllBytes("UpdatedNintexWorkflow.nwf");
            NintexWorkflowWS.NintexWorkflowWS ws = new NintexWorkflowWS.NintexWorkflowWS();
            ws.Url = web.Url + "/_vti_bin/NintexWorkflow/workflow.asmx";
            ws.UseDefaultCredentials = true;

            int i = 1;
            foreach (string listName in listNames)
            {
                ws.PublishFromNWF(rawData, listName, string.Format("NintexWorkflow-{0}", i), false);
                i++;
            }
        }
    }
}

There we are done. Just run the EXE and it will update the workflow to each and every library in a web.

Complete project is available for download here. Please let me know, if you need any more help.

No comments:

Post a Comment