With the release of Visual Studio 2012, most of our customizations for the software factory Endeavour needed to be upgraded from the Beta and RC to the RTM release as well. Since the Team Build workflow of VS 2012 runs on Windows Workflow 4.5, we internally have some solutions that use some compiled xaml workflows to test our team build customizations. During the development of this workflow we ran against this path to long exception from the XamlBuildTask:
Error 148 Extension ‘Microsoft.Activities.Build.BeforeInitializeComponentExtension’ threw an exception of type ‘System.IO.PathTooLongException’ : ‘The specified path, file name, or both are too long. The fully qualified file name must be less than 260 characters, and the directory name must be less than 248 characters.’. <location project>
While process monitor (http://technet.microsoft.com/en-us/sysinternals/bb896645)already told me what was going, the automated Team Build made this point even clearer across:
Exception Message: TF205022: The following path contains more than the allowed 259 characters: $/<not so small path>/obj/Release/<namespace>_<workflow classname>_BeforeInitializeComponentHelper.cs. Specify a shorter path. (type InvalidPathException)Exception Stack Trace: at Microsoft.TeamFoundation.VersionControl.Common.VersionControlPath.GetFullPath(String item, Boolean checkReservedCharacters) at Microsoft.TeamFoundation.VersionControl.Client.Workspace.TryGetServerItemForLocalItem(String localItem, WorkingFolder folders, Boolean detectImplicitCloak) at Microsoft.TeamFoundation.TestImpact.BuildIntegration.BuildActivities.GetImpactedTests.CompareBinary(CodeActivityContext context, String sharePath, String assembly, IList`1 codeChanges) at Microsoft.TeamFoundation.TestImpact.BuildIntegration.BuildActivities.GetImpactedTests.CompareBuildBinaries(CodeActivityContext context, IBuildDefinition definition, IList`1 codeChanges) at Microsoft.TeamFoundation.TestImpact.BuildIntegration.BuildActivities.GetImpactedTests.Execute(CodeActivityContext context) at System.Activities.CodeActivity.InternalExecute(ActivityInstance instance, ActivityExecutor executor, BookmarkManager bookmarkManager) at System.Activities.Runtime.ActivityExecutor.ExecuteActivityWorkItem.ExecuteBody(ActivityExecutor executor, BookmarkManager bookmarkManager, Location resultLocation)
In 4.0 for every workflow a _XamlStaticHelper was created in the generated code file. since this helper had the same name between workflows, this often resulted in many compile warnings when multiple workflows where part of the same namespace. Starting with 4.5 only one _XamlStaticHelper for a complete dll is generated and the BeforeInitializeComponentHelper.cs and txt files are used to hook the things up back to the individual workflows. This path to long exception is caused by the xaml compiler which tries to generate this BeforeInitializeComponentHelper.cs file by prepending the namespace of classname in the workflow (x:Class property) to make the code file unique. Since the namespaces can be quite deep due to naming conventions, this can often result in a path to long.
Currently there are a two workarounds:
- Reduce the namespace in workflow x:Class property. This makes the generated file have a shorter name.
- use the subst or mklink command to create mapping so that the path the solution is located in becomes a lot smaller. In team build, the workspace mapping needs to be modified equally.