TFS 2010自定义构建活动TF215097错误

16

在 TFS 2010 的构建过程中,我创建了一个包含一些自定义代码活动的库。过去,通过将库(*.dll)添加到源代码控制,并将“生成控制器 - 版本控制路径设置为自定义程序集”设置为源代码控制中可找到该库的路径,所有工作都正常。

但是最近几天(我经常更新库),构建无法成功完成。出现的错误如下:

  

TF215097:初始化“无法创建未知类型'{clr-namespace:BuildTasks;assembly=BuildTasks}'”的构建期间发生错误

搜索后,我没有找到其他解决方法,只能将库安装到GAC(全局程序集缓存)。这样做可以解决问题,但我想知道为什么不能在不安装到GAC的情况下使其正常工作。

尽管它现在又开始工作了,但我仍然希望以旧的方式使其工作,而不需要使用GAC。希望你们能够帮助我。先谢谢了。

14个回答

9
如果你想指定包含你编写的自定义代码活动的程序集,需要按照以下步骤操作:
  1. 将你的自定义活动构建到工作流中。
  2. 确保顶部的xmlns被正确定义:xmlns:local="clr-namespace:BuildTasks;assembly=BuildTasks"。
  3. 确保在构建过程的XAML标记中,所使用的本地(或任何你惯用的前缀)是正确的。
  4. 将更新后的工作流XAML检入你的团队项目,并更新你的构建定义。
  5. 在你的团队项目中创建一个名为“CustomBuildAssemblies”的新目录。
  6. 进入用于创建自定义构建任务的项目的bin/Debug(或release)文件夹,并将其中的dll文件(即你要放在GAC中的dll)放入步骤5中创建的目录中。
  7. 通过 Team Exporer 去告诉构建控制器在哪里查找自定义程序集,选择你正在进行此操作的项目,在项目列表中展开并右键单击“构建”,然后选择“管理构建控制器”;选择控制器(应该是列表中的第一项),然后点击属性。将版本控制路径设置为步骤5中创建的目录(位于弹出窗口的中间)。
此时,你有一个引用(导入)已包含在源代码控制中的自定义程序集(或多个)的自定义XAML工作流。构建控制器现在知道这些自定义程序集的位置。这使你可以“检入”新版本的自定义程序集,以便添加/更新自定义构建任务。
希望这会对你有所帮助。我也花了一些时间才弄明白这个过程。如果需要更详细的解释,请告诉我。但我很遗憾不能上传一些对话框的截图。
更新: 我完全忘记了这个主题,直到看到它被重新启动。我还可以更新此答案,因为我找到了一种非常好的方法,可以让TFS拉取你的自定义构建任务程序集的最新版本:为程序集创建一个唯一的版本号。
我使用T4模板,并在构建程序集之前运行它。它在读取已检入的自定义活动DLL之后更新AssemblyInfo.cs。
<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ assembly name="System.Xml.dll" #>
<#@ import namespace="System.Xml" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Reflection" #>
<#@ output extension=".cs" #>
<#

 //relative path to the DLL for your custom assembly in source control
 var filename = this.Host.ResolvePath("..\\..\\..\\..\\BuildAssemblies\\BuildTasks.dll");

 Version buildInfoAssemblyVersion = AssemblyName.GetAssemblyName(filename).Version;

 // Setup the version information. Using the DateTime object make it kinda unique
 var version = new Version(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, buildInfoAssemblyVersion.Revision + 1);

#>
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Windows.Markup;

// General Information about an assembly is controlled through the following 
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("BuildTasks")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Microsoft")]
[assembly: AssemblyProduct("BuildTasks")]
[assembly: AssemblyCopyright("Copyright © Microsoft 2012")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// Setting ComVisible to false makes the types in this assembly not visible 
// to COM components.  If you need to access a type in this assembly from 
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("feab7e26-0830-4e8f-84c1-774268727cbd")]

// Version information for an assembly consists of the following four values:
//
//      Major Version
//      Minor Version 
//      Build Number
//      Revision
//
// You can specify all the values or you can default the Build and Revision Numbers 
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
// Version information is a combination of DateTime.Now and an incremented revision number coming from the file:
// <#= filename #>
[assembly: AssemblyVersion("<#= version.ToString() #>")]
[assembly: AssemblyFileVersion("<#= version.ToString() #>")]

[assembly: XmlnsDefinition("http://localhost/BuildTasks/Activities", "BuildTasks.Activities")]
[assembly: XmlnsDefinition("http://localhost/BuildTasks/Activities/InstallerA", "BuildTasks.Activities.InstallerA")]
[assembly: XmlnsDefinition("http://localhost/BuildTasks/Activities/InstallerB", "BuildTasks.Activities.InstallerB")]
[assembly: XmlnsDefinition("http://localhost/BuildTasks/Activities/CodeAnalysis", "BuildTasks.Activities.CodeAnalysis")]
[assembly: XmlnsDefinition("http://localhost/BuildTasks/Activities/Standards", "BuildTasks.Activities.Standards")]
[assembly: XmlnsDefinition("http://localhost/BuildTasks/Activities/CI", "BuildTasks.Activities.CI")]
[assembly: XmlnsDefinition("http://localhost/BuildTasks/Activities/Version", "BuildTasks.Activities.Version")]

您会注意到底部我还设置了每个工作流中使用的命名空间的XML命名空间定义。我发现生成的XMAL看起来更清晰,并且这也有助于解决我的问题。

我将此文件创建为AssemblyInfo.tt,只需确保在构建程序集之前运行它(右键单击并选择运行T4或类似选项)即可。


3
谢谢您的回复,但我已经按照您描述的方式准确地完成了。起初它也可以工作,但突然间停止了。但是我接受了解决方法;通过将自定义代码活动程序集安装到GAC中,它现在可以工作 :) 我没有时间去弄清楚原因,现在它可以工作了。 - Rhapsody

8
这个解决方案可能并不适用于所有情况,因为之前的帖子中提供的答案是正确的,但不是我遇到问题的解决方案。此答案假定以下内容:
  1. 自定义解决方案程序集都已更改并进行了检入,并且正确地标记和构建了。
  2. 构建控制器已指向自定义程序集所在的正确源代码控制位置。
我怀疑我和其他许多人一样,正在将他们的XAML工作流文档复制或链接到解决方案中,以便使用工作流设计器和新的自定义程序集。嗯,在VS设计器中这很好用,但是VS会使用它自己的修改您的程序集引用。例如,我有一个引用看起来像下面这样:
xmlns:ca="clr-namespace:Custom.TFS.Activities;assembly=Custom.TFS.Activities" 

在使用我的项目解决方案编辑工作流后,Visual Studio更改了它为:
xmlns:local="clr-namespace:Custom.TFS.Activities" 

当您将此文件检入以进行测试或使用时,您现在会看到可怕的TF215097错误。
添加 ;assembly=your.assembly 应该解决问题并消除将所有内容放入 GAC 的需要。您还可能需要修复其余 xaml 文件中使用的命名空间引用。
特别感谢: http://msmvps.com/blogs/rfennell/archive/2010/03/08/lessons-learnt-building-a-custom-activity-to-run-typemock-isolator-in-vs2010-team-build.aspx

1
如果构建任务与您正在编辑的工作流XAML位于同一项目中,则从XMLNS中删除“;assembly=BuildTasks”部分。使用两个单独的项目(一个用于编辑构建模板,一个用于创建自定义构建活动)可以解决此问题,并允许您在设计器中编辑工作流,而无需在每次更改后手动编辑XAML。 - JRS

6
你的codeActivity类需要这个属性:
<BuildActivity(HostEnvironmentOption.All)> _
否则,程序集将无法加载。

1
似乎报告的错误可能有很多原因,但这个方法对我起了作用。 - Paul Hadfield

2
如Rhapsody在2010年6月2日所述,可以使用GAC。但需要注意的是,如果您使用了GAC,则需要停止并重新启动构建服务,以便重新扫描GAC,从而捕获您的DLL。
我最初在GAC中注册了我的DLL,当我启动指向由我定制的代码活动程序集组成的工作流程的构建时,构建失败了。但是,在停止和重新启动构建服务之后,构建不会立即失败,也不会出现可怕的“在为构建定义[BuildDefinitionName]初始化构建时发生错误:无法创建未知类型...”错误。

1

我今天没有找到这个问题的答案,所以对于你们中的一些人来说,可能这个答案已经太晚了。

我一直在尝试从GAC中进行相同的修改命名空间声明,但总是遇到著名的“无法创建未知类型'{clr-namespace:bla,bla,bla}”。每次添加新程序集时修改所有构建模板都是一种痛苦和恼人的经历。我在设置GAC中的程序集时遇到了一些问题,似乎有一些缓存,因为即使我从GAC中卸载并重新安装程序集,自定义活动也没有刷新。

最后,我在http://msdn.microsoft.com/en-us/library/ee330987.aspx中发现,您可以通过将它们添加到源代码控制中并在构建控制器属性中设置自定义程序集的控制路径来添加具有自定义活动的自定义程序集(您可以从Team Foundation Administration Console访问--> Build Configuration --> Controller Properties)

您只需要将程序集添加到源代码控制中,TFS会处理其他所有事项。


1

感谢您的回复,我已经检查了XAML文件,并看到程序集名称已经包含在内:xmlns:b="clr-namespace:BuildTasks;assembly=BuildTasks" 但我会再尝试一下。 - Rhapsody

1

我曾经遇到过完全相同的问题。原因是我使用自定义活动编译库时,针对x86平台进行了编译,而构建控制器正在运行64位Windows 2008虚拟机。将目标平台切换为AnyCPU后,构建控制器立即可以利用该库,而无需将其添加到GAC中。


欢迎来到 Stack Overflow!在发布复制粘贴的模板/逐字回答多个问题时,请小心,这些通常会被社区标记为“垃圾邮件”。如果您这样做,那么通常意味着这些问题是重复的,请将它们标记为重复。 - Kev

1

检查您的Windows事件通知。 可能没有正确加载您的自定义活动DLL。

如果没有加载成功,那么您可能需要更改自定义活动项目的平台目标... 要么是32位或64位。


1
我需要的解决方法是创建一个类的部分类定义,并将BuildActivity属性应用于它。我的问题在于我的活动类上缺少BuildActivity属性,因为我是在松散的Xaml中实现它而不是作为代码活动,所以这个方法对我有用。
据说,Team Build会加载包含BuildActivity或BuildExtension类的任何程序集,并理论上这应该导致该程序集中的任何类可用于构建。这将启用一种虚拟的加载器类,允许加载Xaml活动而无需这些部分类定义,但在实践中,这对我没有起作用。

0

我在这个帖子中尝试了其他答案,但都没有成功,不过我想分享一下我的做法。我的自定义程序集是通过 GAC 加载到构建机器上的。我不得不手动打开构建模板 XAML 文件,并将我的程序集添加到命名空间引用中。由于某种原因,Visual Studio 没有正确地为我引用它。

之前:

xmlns:ba1="clr-namespace:BuildTasks.Activities"

之后

xmlns:ba1="clr-namespace:BuildTasks.Activities;assembly=ModifyTasks"

我自定义的构建任务程序集名为ModifyTasks.dll,请将其替换为您自己的文件名...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接