Resolving Nintex Feature Activation issues after migration

Issues have been reported with data migration tools used to transfer   content from a SharePoint 2010 environment to a SharePoint 2013 environment.   The tools are preventing the Nintex Workflow site collection feature from   activating in the 2013 environment.

Scenario

Site Collection A is in a SharePoint 2010 environment with the Nintex   Workflow 2010 feature activated.

Site Collection B is in a SharePoint 2013 environment without the   Nintex Workflow 2013 feature activated.

A data migration tool is used to move data from a team site in Site   Collection A to a team site in Site Collection B.

Issue

Some data migration tools detect that a site column or content type   from Site Collection A is not present in Site Collection B, and then recreate   these assets at the target team site. In this case, it will recreate a Nintex   Workflow-installed content type and site column.

Later, when a user attempts to activate the Nintex Workflow site   collection feature, it will fail. The message in the SharePoint logs will be   similar to:

The field with Id {c2dd77c1-89a4-4f1f-b037-c17407e9922c}   defined in feature {0561d315-d5db-4736-929e-26da142812c5} was found in the current site collection or in a sub site.

In other words, the data migration tool has forcibly created a column somewhere in the site collection that the feature activation cannot overwrite, preventing it from activating.

Avoiding the issue

This issue will not occur if the Nintex Workflow 2013 site collection   feature is already active on the target site collection prior to migration.

Fixing the issue

Option   1: Activate Feature with Powershell and use the Force

From an administrative SharePoint Powershell:

Put in the folder name of the feature in question in the   “identity” parameter. You can find the folders under

SharePoint   2010:
C:Program FilesCommon Filesmicrosoft sharedWeb Server   Extensions14TEMPLATEFEATURES

SharePoint   2013:
C:Program FilesCommon Filesmicrosoft sharedWeb Server   Extensions15TEMPLATEFEATURES

Example:

Enable-SPFeature –identity "NintexWorkflowInfopath" -URL <a href="https://go.mysite.com/mysitecollection/">https://go.mysite.com/mysitecollection/</a> -force

Option 2: Feature Site Column Cleanup Tool

In response to this issue, Nintex developed a utility to clean up any site columns and content types that exist in a sub site in a site collection.

This tool recursively searches every site in a site collection, checking for all Nintex Workflow content types and site columns, and optionally attempts to delete these assets.

It will print the location of any founds assets to the console window.

Once the assets have been removed, the site collection feature will activate correctly.

The tool is available from http://download.nintex.com/sl/supportfiles/support_utilities/NW2010/FeatureSiteColumnCleanup.zip

It should be downloaded to a SharePoint server and run from a command console window as an account that has access to modify all sites in the site collection.

Depending on the number of subsites in the site collection, the tool may take some time to run. The tool will print “Process complete” to the console window when it has finished processing.

Usage

FeatureSiteColumnCleanup.exe "siteCollectionUrl" [-deleteFound] [-includeRootWeb] [-searchUsage] [-skipFields] [-skipContentTypes]

siteCollectionUrl: The URL to the top level site of the site collection that requires processing.

-deleteFound: If this argument is included, any found content types of site columns will be deleted. If this argument is not included, the tool will only report the location of these fields.

-includeRootWeb: If this argument is included, the root team site will be included in the search for assets. Please note that if the Nintex Workflow feature has activated correctly, the assets will exist at the root team site and should not be deleted.

-searchUsage: Specifies whether each list on each site should be checked to see if it uses a Nintex Workflow content type

-skipFields: Specifies whether the process should not check for field assets

-skipContentTypes: Specifies whether the process should not check for content type assets

Example

FeatureSiteColumnCleanup.exe "<a href="http://sharepoint/sites/portal">http://sharepoint/sites/portal</a>" –deleteFound

From <http://connect.nintex.com/forums/thread/12937.aspx>

Option 3: SQL Method aka “Hammer of Thor”

Warning: Unsupported by Microsoft and most likely Nintex!

Identify the Nintex-related Content Type GUID’s and update their “IsFromFeature” property to 0, in the relevant content databases.

Update [dbo].[ContentTypes] set [IsFromFeature] = 0 where (sys.fn_varbintohexstr(ContentTypeId) LIKE '0x0101EF0201%')

Update [dbo].[ContentTypes] set [IsFromFeature] = 0 where (sys.fn_varbintohexstr(ContentTypeId) LIKE '0x010801005CC0%')

Update [dbo].[ContentTypes] set [IsFromFeature] = 0 where (sys.fn_varbintohexstr(ContentTypeId) LIKE '0x0108010064E42%')

Update [dbo].[ContentTypes] set [IsFromFeature] = 0 where (sys.fn_varbintohexstr(ContentTypeId) LIKE '0x0108010079DBDE6%')

Update [dbo].[ContentTypes] set [IsFromFeature] = 0 where (sys.fn_varbintohexstr(ContentTypeId) LIKE '0x01010024055%')

Update [dbo].[ContentTypes] set [IsFromFeature] = 0
where (sys.fn_varbintohexstr(ContentTypeId) LIKE '0x01010024055%')

Update [dbo].[ContentTypes] set [IsFromFeature] = 0
where (sys.fn_varbintohexstr(ContentTypeId) LIKE '0x010100F815D979%')

Update [dbo].[ContentTypes] set [IsFromFeature] = 0
where (sys.fn_varbintohexstr(ContentTypeId) LIKE '0x010100F8376F531%')

Update [dbo].[ContentTypes] set [IsFromFeature] = 0
where (sys.fn_varbintohexstr(ContentTypeId) LIKE '0x010100240555%')

Nintex Workflow Performance Improvement and Load Reduction

Nintex Workflow utilizes the SharePoint workflow engine, which in turn is built on the Windows Workflow Foundation. Like with many aspects of SharePoint, there are certain performance limitations and common errors that can be encountered, not all of which are documented. This document has been compiled to address common issues that we have discovered over time such as workflows taking a long time to process, publish and start, as well as errors such as “Failing to start (retrying)”.

There are a number of different factors which can affect the performance and success of workflows, which are fully outlined. This document provides guidance on identifying, responding to and avoiding these issues.

Download (.PDF): https://community.nintex.com/docs/DOC-1307

1 Contents ………………………………………………………………………………………………………………………… 1
2 Conceptual overview ………………………………………………………………………………………………………. 3
3 Workflow size and performance ……………………………………………………………………………………….. 4
3.1 The workflow takes a long time to start and/or publish ……………………………………………….. 4
3.2 Resources used when a workflow starts …………………………………………………………………….. 5
3.3 Workflows are failing with specific errors …………………………………………………………………… 5
3.4 Architectural considerations ……………………………………………………………………………………… 5
4 Common errors and issues ………………………………………………………………………………………………. 6
4.1 Common error messages ………………………………………………………………………………………….. 6
4.1.1 Cannot find a corresponding human workflow task ID for this task ………………………… 6
4.1.2 This task is currently locked by a running workflow and cannot be edited. ……………… 6
4.1.3 Failed to start (retrying) …………………………………………………………………………………….. 6
4.2 Common issues ……………………………………………………………………………………………………….. 7
4.2.1 Timeout errors when updating an item. ………………………………………………………………. 7
4.2.2 Multiple workflows accessing/updating an item at the same time …………………………. 8
4.2.3 Actions not displaying correctly in the workflow designer UI (Nintex Workflow 2007) 9
5 Key Nintex Workflow design factors in reducing system load ……………………………………………… 10
5.1 Task list issues and the amount of approval actions used ……………………………………………. 10
5.2 Certain actions have a heavier processing load ………………………………………………………….. 10
5.3 Delay actions (state machine/loops) ………………………………………………………………………… 10
5.4 Amount of concurrent workflow processes running/workflows starting at the same time 11
6 To split or not to split – preliminary considerations before breaking up a large workflow ……… 12
6.1 Increase the time-out of the timer service ………………………………………………………………… 12
6.2 Increase the SharePoint Workflow time-out: …………………………………………………………….. 13
7 Splitting a workflow process into smaller sequential workflows …………………………………………. 14
7.1 Advantages of splitting a workflow into separate sub processes ………………………………….. 14
7.1.1 Avoiding the repetition of a long, complex process …………………………………………….. 14
7.1.2 Ease of troubleshooting …………………………………………………………………………………… 14
Nintex – Workflow performance improvement and load reduction Page 2 of 22
7.1.3 Eliminating time-outs ………………………………………………………………………………………. 14
7.2 Disadvantages ……………………………………………………………………………………………………….. 15
7.2.1 Understanding your process at a glance …………………………………………………………….. 15
7.3 Approach to splitting………………………………………………………………………………………………. 15
8 Appendix 1 – How the “Commit pending changes” action works and when it is best used …….. 18
8.1 The “Commit pending changes” workflow action: ……………………………………………………… 18
8.1.1 Actions that are processed in the SharePoint batch …………………………………………….. 19
8.1.2 Actions that are processed in the Nintex batch …………………………………………………… 19
8.1.3 Hybrid actions ………………………………………………………………………………………………… 19
9 Appendix 2 – Checking performance on your server ………………………………………………………….. 21

Broken Links and Images in SharePoint Emails – A Nintex Fix Up

If you are experiencing broken images (URL’s) and links in notification emails coming from SharePoint, it may be due to a discrepency between how image and link assets are referenced in the blog posts (using only a /relative URL instead of a http://FQDN/ -based URL).

Although brittle in that it only corrects the link structure we specifically reference, the following approach does have the effect of re-basing the URL’s inside the content of the posts, so that they get their server name pre-pended and the images/links display & work as expected:

What

When viewing the contents of a SharePoint blog post in a notification email, for example,
images and links will be broken because their URL’s are missing the servername.

For example;
Image is trying to go to: http://blogs/Lists/Posts/Attachments/777/myimage.png
instead of https://go.mysharepoint.com/blogs/Lists/Posts/Attachments/777/myimage.png
..and so displays as a nasty red X (or nothing at all) in your users email client.

So What

So, Nintex to the rescue:
In the workflow that emails our staff notifications of the new blog post (including the blog post content), we do some string replacements on the body of the email:

1. Create a new Muliline Text variable called vOutputText
2. Create a new Regular Expression Action in your Nintex workflow:

Pattern (ignore case): src=”/blogs/Lists/
Operation: Replace Text
Replacement Text: src=”http://go.mysharepoint.com/blogs/Lists/
Store Result In: vOutputText

3. Rinse and repeat step two for each variation of links you encounter in your posts. You may find that authors consistently use other SharePoint Document Library, List and Site link patterns in their posts. You should add a new regex for each one of those.
4. Set the vOutputText to be the content of your notification email action.
5. Fire up the workflow and the email containing your blog post content should display the rebased URLs you addressed as expected.

Now What

Emails sent out now will have full URL’s in the elements you addressed and thus the links and images should work properly when the end user views the email in their client.

That being said – as mentioned this is a basic & brittle approach – chances are other link patterns will sneak in there and you’ll still get broken links when people reference new parts of your SharePont site that you didn’t account for. If you care to go deeper into Regular Expressions, the Nintex Regular Expression action is fully capable of supporting more advanced expressions that would be able to rebase URL’s that are missing their root domain name and not get tripped up on differences in subfolder paths. Since this is a Nintex Action lesson and not a Regular Expression lesson, I will refer you MSDN for learning more about Regular Expressions and to the great program RegexBuddy for developing and testing your fabulous new bullet-proof Regex’s.

 

itgroove Nominated as Finalist by Nintex

In case you missed it, our SharePoint + Nintex + Muhimbi solution for BC Ferries recently got us a nomination the first ever Nintex Partner awards. The results are in, and congratulations to Buchanan & Edwards for winning and thanks again to Sean, Colin, and our friends at BC Ferries, Nintex & Muhimbi for all working hard on this project. It’s great to be able to build a solution that contributes directly to safe, efficient, and environmentally friendly transportation. Whenever we take a ferry ride in BC we can now think about this project as an example of how IT can produce direct improvements in business and lives.

Nintex Upgrade / Install Failure – SecurityException

If you are upgrading or installing Nintex (and, as you will learn, pretty much any other .NET app/solution/web part/widget etc.) you may run into a fail whale in the form of the the error described on this post on the Nintex Forums

“Trying to upgrade my PRODUCTION server to the latest build of Nintex WF 1.11.1

At the end of the upgrade process I get a Windows Command prompt window with the following text:

Upgrading solution package…
System.Security.SecurityException: Access denied.
at Microsoft.SharePoint.Administration.SPSolutionLanguagePack.CheckPermissionJobScheduled()
at Microsoft.SharePoint.Administration.SPSolutionLanguagePack.UpgradeCabFile(String path)
at Microsoft.SharePoint.Administration.SPSolutionLanguagePack.Upgrade(Stringpath, DateTime dt)
at Microsoft.SharePoint.Administration.SPSolution.Upgrade(String path, DateTime dt)
at Nintex.Installer.WSSHelper.Program.DeployWSP(String[] args)
The Zone of the assembly that failed was:
MyComputer
Press any key to continue…

While the advice offered in that thread regarding using MSIEXEC works, it’s important that one understands the simple cause and effect for this issue : one needs to Right-Click on the file in Windows Explorer and “Unblock” it before attempting to execute it. This also is a simple remedy for preventing similar issues with lot’s of .NET related installables, .DLLs, solutions etc.

You simply need to “Unblock” the installable file to prevent this situation from occuring – it is common for UAC in Windows to block executable or compilable code downloaded from the Internet Zone. Unless you explicitly unblock it, this type of error will occur. Had the MSI or file/code/.DLL been copied/compiled/executed locally in Visual Studio/via the installer etc. , the newly generated .dll or unpacked program files would have been in the same Zone (the My Computer Zone) as the rest of the .Net assemblies for the web application. The problem would not occur.

You will often encounter warnings when downloading the files (note: these warnings are not exclusive to .MSI or .CHM installer file types but also can occur for .ZIP’s, .DLL’s and other formats):

The Nitty Gritty Details

This file / directory blocking is provided by default on:

Windows XP SP2 with IE 7
Later Windows, like Windows Vista, 7

And marking the file / directory as blocked / unblocked is implemented via alternative data stream feature, which is a feature of NTFS file system. The alternative data streams are just some data like key-value pairs attached on a file or folder.
In the above scenarios, since the file in this scenario was downloaded from an internet location, the file is marked by set such key-value pair:

key (data stream name): Zone.Identifier;
value (data stream content): [ZoneTransfer]
ZoneId=3

Here

1 = trusted;
2 = intranet;
3 = Internet;
4 = untrusted.

The above alternative data stream can be examined via command line:

more < MyCodeFile.zip:Zone.Identifier

That is how is MyCodeFile.zip file marked as blocked to enhance the security, and a “Unblock” button appears on the property dialog.
Actually any file / directory marked with this Zone.Identifier alternative data stream is considered from Internet and blocked by the Windows. A test.txt file can be created to test this:

echo test > test.txt

by checking its property, this test.txt is unblocked of course. Now inject the same Zone.Identifier alternative data stream into test.txt:

more < MyCodeFile.zip:Zone.Identifier > test.txt:Zone.Identifier

By clicking the “Unblock” button, the key-value pair is removed from the file, so the file is treated as unblocked by Windows.

If the files in the MyCodeFile.zip are extracted without unblocking the MyCodeFile.zip, those file will also have the same alternative data stream, indicating they are from Internet. So they are blocked, just like the above test file.

Resolution 1 – The Just get this damn app working approach

1. Roll back your code changes – this means uninstall any new .DLL’s, solutions, components that you may have added, or cancel out of the MSI install routine you were attempting.
2. Ensure that any new .DLL’s/code/files that are applied by the change are unblocked (right click on the file in Windows Explorer and click unblock). If you have one .ZIP file with a bunch of .DLL’s and other code inside it, it’s only necessary to unblock the root .ZIP file itself.
3. Re-apply code changes
4. If Application doesn’t come back to life give IIS a kick in the head with an IISRESET.exe

Resolution 2 – Change Workstation Config So Files Don’t Get Blocked Like this In Future

Several ways can be used to remove the Zone.Identifier data stream to unblock file / directory:

-Configure Windows to disable this feature (described below)

-Use command lines
-Use streams.exe provided in Sysinternals Suite (technique described here)
-Programmatically remove the data stream
-Registry Tweak to take ownership of a folder (technique described here)

Please review the following links that explain why this security exception is occurring
http://weblogs.asp.net/dixin/archive/2009/03/14/understanding-the-internet-file-blocking-and-unblocking.aspx
http://www.securityfocus.com/infocus/1822
http://en.wikipedia.org/wiki/Fork_(filesystem)
http://blogs.msdn.com/b/friis/archive/2010/06/09/system-security-securityexception-request-for-the-permission-of-type-system-web-aspnethostingpermission-failed.aspx
http://anotherlab.rajapet.net/2010/08/resolving-to-webpage-was-canceled-with.html

In completely unrelated news, it’s Yalla, the underwater cat:

Nintex Custom Actions permissions – Understanding RunWithElevatedPrivileges

When trying to do a simple System.IO.File.Copy inside the context of a Custom Nintex Action I wrote, I found that I couldn’t get the file to copy to a particular Windows Server File Share. Even though I had assigned the user name that was running the Nintex Workflow Read/Write permissions on the share, it would fail with an error indicating lack of access to that folder.

It worked ok if I set “Everyone” with Read/Write permissions. Reviewed the great article on Windows Server 2008 File Share setup at http://www.techotopia.com/index.php/Configuring_Windows_Server_2008_File_Sharing , still it was clear the File Share was just net configured right.

The source of the issue is that in running the File Copy code inside a RunWithElevatedPrivileges block, it is actually using a different account than the one running the workflow. Here is the Nintex Execute Activity function in question:

protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
		{
			NWWorkflowContext ctx = NWWorkflowContext.GetContext(
			   this.__Context,
			   new Guid(this.__ListId),
			   this.__ListItem.Id,
			   this.WorkflowInstanceId,
			   this);

			base.LogProgressStart(ctx);
				SPSecurity.RunWithElevatedPrivileges(() =>
				{
					if (!Directory.Exists(ctx.AddContextDataToString(OutputPath)))
						Directory.CreateDirectory(ctx.AddContextDataToString(OutputPath));
					File.Copy(ctx.AddContextDataToString(SourcePath) + ctx.AddContextDataToString(strFileName),ctx.AddContextDataToString(OutputPath) + ctx.AddContextDataToString(strFileName),true);
				});
			}
			catch (Exception ex2)
			{
			    EventLog.WriteEntry("CopyFile Create Exception - Source File [" + SourcePath + strFileName + "] Output File [ " + OutputPath + strFileName + "]", ex2.Message + ", StackTrace: " + ex2.StackTrace, EventLogEntryType.Error, 9999);
			}
			base.LogProgressEnd(ctx, executionContext);
			return ActivityExecutionStatus.Closed;
		}

The thing to remember regarding this method call is that the account NAME that is being used is “SHAREPOINT/SYSTEM” and this does not resolve to an actual domain account. Now the only time this becomes and issue is when one is referring to Windows resources outside of SharePoint. Again this is only intended to be used for resources within SharePoint. If your function code is say calling even a SharePoint web service and one sets the web service “Credential” to “System.Network.CredentialCache.DefaultNetworkCredential” that the service call will in fact fail because IIS will not be able to resolve the domain account “SHAREPOINT/SYSTEM”. If the case is one needs to access external data then consider using a Secure Store credentials.

I’ve always found that the nuances of RunWithElevatedPrivileges cause much confusion as well as some weird and wonderful behavior if not properly understood. While the documentation here does a good job of explaining how and when to use it, it’s missing a key piece of information and that’s how the mechanism actually works.

Behind the scenes, RunWithElevatedPrivileges impersonates the identity of the current thread. In effect, this means that the delegate will run under the context of the application pool account, in the case of the code being called in the W3P process, or in the context of the SPTimerv4 service, in the case of the code being called in a workflow, timer job or anything else that’s kicked off using the timer. If the code is running in a console application or some other user-initiated app, the delegate will be kicked off using the context of the user who started the application. (Which would be the default behavior anyway).

When using workflows, bear in mind that the workflow may start running under W3P but continue executing under owstimer (SPTimerV4) depending on what it’s actually doing. In this case a delegate executed using RunWithElevatedPrivileges would not neccesarily yeild the same result.

PS nifty trick if you’ve forgotten about it: just add a $ to the end of the share name (rendering it accessible but invisible when people browse the shares).

Nintex – Specified value is not supported for the urlOfFile parameter

Recently after a Ninxtex migration/version update we encountered the following error when trying to publish any workflow:

Windows Event Log Error:
System.ArgumentException: urlOfFile Parameter name: Specified value is not supported for the urlOfFile parameter.
at Microsoft.SharePoint.SPFileCollection.get_Item(String urlOfFile)
at Nintex.Workflow.WorkflowRepository.NameInUse(String workflowName, Guid listId, WorkflowType& workflowType)
at Nintex.Workflow.ApplicationPages.SetName.Page_Load(Object sender, EventArgs e)
at System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e)
at System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e)
at System.Web.UI.Control.OnLoad(EventArgs e)
at Microsoft.SharePoint.WebControls.UnsecuredLayoutsPageBase.OnLoad(EventArgs e)
at Microsoft.SharePoint.WebControls.LayoutsPageBase.OnLoad(EventArgs e)
at Nintex.Workflow.ServerControls.NintexLayoutsBase.OnLoad(EventArgs e)
at Nintex.Workflow.ApplicationPages.SetName.OnLoad(EventArgs e)
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

To resolve this, go to the hidden NintexWorkflows library and check the contents of each subfolder. If your site is http://farm/sites/test the URL would be http://farm/sites/test/NintexWorkflows. If any subfolder is empty (contains no files), delete the subfolder – you should be able to publish after that.

SpSite in Nintex Workflow Custom Action

So today I needed to get the URL of the current SharePoint site my Nintex Custom Action Visual Studio solution is executed under, using the SPSite class. Problem was, was not working on the server of the SPSite. Nor would I want to have to install Visual Studio on the production instance where the solution was to live.

Makes sense, just need to grab the httpcontext. SPContext.Current.Site seemed to fit the bill, but alas, it did not work. Lost some time hunting for a solution to the following error:

Could not create activity of type 'CustomActions.MyCustomActivity'. System.IO.FileNotFoundException: The Web application at http://xxx.xxx.com could not be found. Verify that you have typed the URL correctly. If the URL should be serving existing content, the system administrator may need to add a new request URL mapping to the intended application.
at Microsoft.SharePoint.SPSite..ctor(SPFarm farm, Uri requestUri, Boolean contextSite, SPUserToken userToken)
at Microsoft.SharePoint.SPSite..ctor(String requestUrl)

There’s a number of possible causes and it took going through some pain in order to resolve which route to take. The standard contingencies are explained quite well on http://www.thorntontechnical.com/tech/sharepoint/new-spsite-filenotfoundexception. None of those, possibly valid error causes, solved my beef.

In the end I found that we don’t actually need to be local with VS on the SharePoint server the solution is compiled against- it was just a matter of finding out how to reference the application context: the Nintex way. In this case, it was being handled by Nintex and the method used was not seemingly explained in the SDK or documented. Looking a bit deeper it became clear the application context was being fed in by Nintex.

Working from the DeployWorkflowActionWithFeature example in the Nintex Workflow 2010 SDK, we can see that in the EventLogAdapter.cs in the project, the context is initially set up in the following function:

public override CompositeActivity AddActivityToWorkflow(PublishContext context)
        {
            EventLogActivity activity = new EventLogActivity();

            Dictionary<string, ActivityParameterHelper> parameters = context.Config.GetParameterHelpers();

            parameters[Parameter_Message].AssignTo(activity, EventLogActivity.MessageProperty, context);
            parameters[Parameter_EventSource].AssignTo(activity, EventLogActivity.EventSourceProperty, context);

            activity.SetBinding(EventLogActivity.__ContextProperty, new ActivityBind(context.ParentWorkflow.Name, StandardWorkflowDataItems.__context));
            activity.SetBinding(EventLogActivity.__ListItemProperty, new ActivityBind(context.ParentWorkflow.Name, StandardWorkflowDataItems.__item));
            activity.SetBinding(EventLogActivity.__ListIdProperty, new ActivityBind(context.ParentWorkflow.Name, StandardWorkflowDataItems.__list));

            ActivityFlags f = new ActivityFlags();
            f.AddLabelsFromConfig(context);
            f.AssignTo(activity);

            context.ParentActivity.Activities.Add(activity);
            
            return null;
        }

That function sets up the __context for use in EventLogActivity.cs as follows:

public static DependencyProperty __ContextProperty = DependencyProperty.Register("__Context", typeof(WorkflowContext), typeof(EventLogActivity));

Now that we have that rolling, we can use the __Context object with SPSite to get our current application URL.
SO, instead of using this:

SPSite site = new SPSite(“http://mysite/sitename”);

Use this:

SPSite site = new SPSite(this.__Context.Site.Url);

You now have the basis to perform all the wonderful SharePoint API stuff you need to do within the context of the Nintex Custom Action.

Version History in SharePoint via SQL

Recently I posted about how to get check-in comments with Nintex via MS SQL – turns out there was a bit more complexity involved in the structure of the version history then first thought (surprise surprise). Below is the stored procedure created to reliably extract the highest MAJOR version of a SharePoint document. So, if a document is currently v5.4 in your SharePoint library, this will grab the 5.0 version:

USE [MySharePoint_Content_DB]
GO
/****** Object:  StoredProcedure [dbo].[proc_GetDocVersion]    Script Date: 02/17/2012 13:37:36 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[proc_GetDocVersion](
@LeafName nvarchar(260)
)
AS
SET NOCOUNT ON

SELECT TOP 1 x.UIVersion FROM (

SELECT
AllDocVersions.UIVersion
AS UIVersion
FROM
AllDocVersions
JOIN AllDocs ON AllDocs.[ID]= AllDocVersions.[ID]
WHERE
AllDocs.LeafName = @LeafName
AND ((CONVERT([nvarchar],AllDocVersions.UIVersion/(512),0)+'.')+ CONVERT([nvarchar],AllDocVersions.UIVersion%(512),0)) LIKE '%.0'
UNION ALL
SELECT
AllDocs.UIVersion
As UIVersion
FROM
AllDocs
WHERE
AllDocs.LeafName = @LeafName
AND ((CONVERT([nvarchar],AllDocs.UIVersion/(512),0)+'.')+ CONVERT([nvarchar],AllDocs.UIVersion%(512),0)) LIKE '%.0'

) x
ORDER BY UIVersion Desc;

Accessing the SQL DB in SharePoint 2010 directly (as opposed to using the SharePoint API’s etc.) is generally considered a cowboy maneuver and can get in you in lot’s of trouble with inconsistent results as well as performance hits. Use this SQL at your own risk, if not as just a means to better understand the plumbing that goes on in the basement of SharePoint.

Additionally, note that if you are accessing version history via the /vti_history// method, there are some major caveats as described in the following (note it’s referring to SP 2007 which uses single-digit version numbers but the description of the potential run-on situation still applies): http://blogs.msdn.com/b/roberthorvick/archive/2007/01/04/wss-rant-linking-to-the-latest-version-of-a-sharepoint-document-considered-harmful-lessons-6-and-7.aspx

  • 1
  • 2