1

我们最近对我们的 ASP.NET 网站解决方案进行了一些代码重组,我遇到了一个关于 TFS 2010 SDK 程序集的不友好问题,我无法弄清楚。

我们有一个小类(我在下面包含了使用 TFS SDK 的函数),它检索自上次部署网站以来的所有 TFS 变更集注释。该网站项目有以下使用 TFS SDK 的参考:

  • Microsoft.TeamFoundation.Client
  • Microsoft.TeamFoundation.VersionControl.Client

曾经存在于项目的 App_Code 文件夹中的类和以下 TFS 程序集部署在站点的 bin 文件夹中:

  • Microsoft.TeamFoundation.Client.dll
  • Microsoft.TeamFoundation.Common.dll
  • Microsoft.TeamFoundation.Common.Library.dll
  • Microsoft.TeamFoundation.dll
  • Microsoft.TeamFoundation.VersionControl.Client.dll
  • Microsoft.TeamFoundation.VersionControl.Common.dll

部署到站点时,这可以正常工作,没有错误。

我们将这个类(连同其他几个)移到一个单独的类库中,并将其从站点的 App_Code 文件夹中删除,更改了 Visual Studio 中项目的所有适当程序集引用。现在,当它被部署时,我们在网站上点击的任何页面上都会收到以下错误:

无法加载文件或程序集“Microsoft.TeamFoundation.WorkItemTracking.Client.Cache, Version=10.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a”或其依赖项之一。试图加载格式不正确的程序。

我可以从我的本地主机和开发工作区运行而没有任何问题,因此构建的某些内容似乎有问题。在检查了 TFS 抽出的构建后,TFS SDK 的构建中包含了另外三个以前不存在的程序集:

  • Microsoft.TeamFoundation.WorkItemTracking.Client.Cache.dll
  • Microsoft.TeamFoundation.WorkItemTracking.Client.DataStore.dll
  • Microsoft.TeamFoundation.WorkItemTracking.Client.RuleEngine.dll

我不明白为什么这些现在被拉进构建中。我们不会在任何项目中直接引用这些程序集。从 TFS 中提取注释的代码没有改变,只是它的程序集位置。未执行任何 TFS 升级。底线 - 我们添加了一个类库,代码现在存在于其中,并且它似乎需要一些其他程序集,而以前它存在于 App_Code 文件夹中时并不想要这些程序集。我最好的猜测是 TFS 在构建过程中将这些作为依赖程序集拉入其他程序集,但我不知道为什么。

类似错误的在线点击通常围绕 32/64 位问题。我检查了配置管理器,解决方案中的所有项目都设置为使用任何 CPU,这对我来说似乎是正确的,我们在服务器上的 IIS 中启用了 32 位应用程序。

对于这篇文章的篇幅,我深表歉意,但我想提供我认为相关的细节。任何想法将不胜感激。谢谢。

Public Function GetChangesSinceDeployDate(ByVal lastDeployDate As DateTime) As List(Of TFSChange)

    Dim tfs As New TfsTeamProjectCollection(New Uri("http://tfs.proviadoor.com:8080/tfs/entrylink"))
    tfs.EnsureAuthenticated()

    Dim vcs As VersionControlServer = CType(tfs.GetService(GetType(VersionControlServer)), VersionControlServer)

    Dim versionFrom As VersionSpec = GetDateVSpec(lastDeployDate)
    Dim versionTo As VersionSpec = GetDateVSpec(Now)

    _changeList = New List(Of TFSChange)

    Dim changeSetIds As String = ""
    For Each projectPath As String In _projectPaths
        Dim results As IEnumerable = vcs.QueryHistory(projectPath, VersionSpec.Latest, 0, RecursionType.Full, "", versionFrom, versionTo, Integer.MaxValue, False, True)

        For Each chgSet As Changeset In results
            If Not chgSet.ChangesetId.ToString().InList(changeSetIds) Then
                _changeList.Add(New TFSChange(chgSet.ChangesetId, chgSet.Committer, chgSet.CreationDate, chgSet.Comment))
                changeSetIds.Append(chgSet.ChangesetId.ToString(), ",")
            End If
        Next
    Next

    Dim sortedList = From chg As TFSChange In _changeList _
                     Select chg _
                     Order By chg.CommitUser, chg.ChangeDate Descending

    Return sortedList.ToList()

End Function

Private Function GetDateVSpec(ByVal versionDate As DateTime) As VersionSpec

    Dim dateSpec As String = String.Format("D{0:yyy}-{0:MM}-{0:dd}T{0:HH}:{0:mm}", versionDate)
    Return VersionSpec.ParseSingleSpec(dateSpec, "")

End Function
4

1 回答 1

0

消息“程序格式不正确”确实表明存在 32/64 位问题。

问题是“任何 CPU”代码将以最高位启动:在您的情况下,是 64 位,因为在启动时引用的所有程序集都是 64 位(或至少是任何 CPU)。

.NET 中延迟程序集加载/JIT 的某种组合意味着在您点击方法调用之前不会实际加载 TFS 程序集。此时,您的应用程序已经承诺以 64 位运行,因此加载 32 位 TFS 程序集失败 - 您不能在一个进程中混合位。 在 IIS 中允许32 位应用程序是不够的:您必须通过更改编译设置来确保您的应用程序确实以 32 位方式运行。在这种情况下,“任何 CPU”实际上是罪魁祸首,因为它允许您的代码以 64 位启动。

我说“某种组合”是因为我不确定确切的细节,但我在控制台应用程序中看到了完全相同的问题,编译为 Any CPU 并引用 TFS DLL。解决方案是将入口点程序集编译为 32 位。在 Web 服务中使用相同的代码的地方,我们最终选择了一个单独的进程,这样 Web 应用程序也不会减少到 32 位。

于 2012-11-29T08:25:52.790 回答