【问题标题】:TFS Not Loading Custom AssembliesTFS 不加载自定义程序集
【发布时间】:2014-09-02 09:04:10
【问题描述】:

我在尝试让构建控制器/代理从构建过程模板中使用的参考中获取自定义程序集时遇到问题。

我已经在多个博客中广泛阅读过这个问题,但很遗憾我无法解决这个问题:

]

我可以确认以下几点:

  1. 没有更新的 TFS 2012 Visual Studio 2013,更新 1(创建 活动并升级构建过程模板)

  2. 一个带有多个代理的构建控制器

  3. TFS 程序集签入并在源代码控制中

在构建控制器中设置正确的路径并重新启动服务:

按照这些博客中使用的指南,自定义活动在模板中正确解析:

http://www.ewaldhofman.nl/post/2010/04/29/Customize-Team-Build-2010-e28093-Part-4-Create-your-own-activity.aspx

http://blogs.msdn.com/b/jimlamb/archive/2010/02/12/how-to-create-a-custom-workflow-activity-for-tfs-build-2010.aspx

我可以查看构建过程模板的 XAML 中的引用,它看起来很好,没有验证错误,而且我的代码活动似乎已正确实现。

代码如下:

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Activities;
using System.Text.RegularExpressions;
using Microsoft.TeamFoundation.Build.Client;
using Microsoft.TeamFoundation.VersionControl.Client;

namespace FireWatch.TFS
{
    [BuildActivity(HostEnvironmentOption.Agent)]
    public sealed class AssemblyUpdater : CodeActivity
    {
        #region Static Methods
        #endregion   

        #region Property Variables
        #endregion

        #region Constants and Read-Onlys
        private const string ASSEMBLY_VERSION_REG_EX = @"\(""\d+\.\d+\.\d+\.\d+""\)";
        private const string ATTRIBUTE_REG_EX = "AssemblyVersion";
        #endregion

        #region Accessors

        [RequiredArgument]
        public InArgument<int> Major { get; set; }
        [RequiredArgument]
        public InArgument<int> Minor { get; set; }
        [RequiredArgument]
        public InArgument<int> Build { get; set; }
        [RequiredArgument]
        public InArgument<Workspace> Workspace { get; set; }

        #endregion

        #region Encapsulation

        private void UpdateAssemblyInfo(IEnumerable<string> assemblyInfos, int major, int minor, int build)
        {
            foreach (string myAssemblyInfo in assemblyInfos)
            {
                string myFileText = File.Exists(myAssemblyInfo) ? File.ReadAllText(myAssemblyInfo) : string.Empty;

                if (myFileText != string.Empty)
                {
                    Regex myRegex = new Regex(ATTRIBUTE_REG_EX + ASSEMBLY_VERSION_REG_EX);
                    Match myMatch = myRegex.Match(myFileText);

                    if (myMatch.Success)
                    {
                        string myVersionNumber = myMatch.Value.Substring(ATTRIBUTE_REG_EX.Length + 2,
                                                 myMatch.Value.Length - ATTRIBUTE_REG_EX.Length - 4);

                        Version myCurrentVersion = new Version(myVersionNumber);
                        Version myNewVersion = new Version(major, minor, build, (myCurrentVersion.Revision + 1));

                        string myUpdatedAssemblyText = myRegex.Replace(myFileText, ATTRIBUTE_REG_EX + "(\"" + myNewVersion + "\")");

                        File.WriteAllText(myAssemblyInfo, myUpdatedAssemblyText);
                    }
                }
            }
        }

        private void CheckOut(Workspace workspace, IList<string> assemblyInfos)
        {
            if (workspace != null && assemblyInfos != null && assemblyInfos.Any())
            {
                workspace.PendEdit(assemblyInfos.ToArray());
            }
        }

        private IEnumerable<string> GetRelevantAssemblyInfos(Workspace workspace)
        {
            IList<string> myReturn = new List<string>();

            PendingChange[] myPendingChanges = workspace.GetPendingChanges();

            foreach (PendingChange myPendingChange in myPendingChanges)
            {
                string myPath = AssemblyInfoPresent(myPendingChange);

                if (!string.IsNullOrEmpty(myPath))
                {
                    myReturn.Add(myPath);
                }
            }

            return myReturn;
        }

        private string AssemblyInfoPresent(PendingChange pendingChange)
        {
            string myReturn = string.Empty;

            if (pendingChange != null)
            {
                string myParentDirectory = pendingChange.LocalItem;
                string myParentLevelAssemblyInfo = myParentDirectory + @"\AssemblyInfo.cs";

                string myPropertiesDirectory = pendingChange.LocalItem + @"\Properties";
                string myPropertiesLevelAssemblyInfo = myParentDirectory + @"\Properties\AssemblyInfo.cs";

                if (Directory.Exists(myPropertiesDirectory) && File.Exists(myPropertiesLevelAssemblyInfo))
                {
                    myReturn = myPropertiesLevelAssemblyInfo;
                }
                else if (Directory.Exists(myParentDirectory) && File.Exists(myParentLevelAssemblyInfo))
                {
                    myReturn = myParentLevelAssemblyInfo;
                }
            }

            return myReturn;
        }

        #endregion

        #region CodeActivity Members

        protected override void Execute(CodeActivityContext context)
        {
            int myMajor = context.GetValue(this.Major);
            int myMinor = context.GetValue(this.Minor);
            int myBuild = context.GetValue(this.Build);
            Workspace myWorkspace = context.GetValue(this.Workspace);

            IList<string> myAssemblyInfos = GetRelevantAssemblyInfos(myWorkspace).Distinct().ToList();

            if (myAssemblyInfos.Any())
            {
                CheckOut(myWorkspace, myAssemblyInfos);
                UpdateAssemblyInfo(myAssemblyInfos, myMajor, myMinor, myBuild);
            }
        }

        #endregion
    }
}

【问题讨论】:

    标签: tfs process build assemblies


    【解决方案1】:

    您是否重新启动了机器?尝试清除构建机器上的缓存

    C:\Users\ BUILDACCOUNT\AppData\Local\Temp\BuildController\2.0\Assemblies

    C:\Users\ BUILDACCOUNT\AppData\Local\Temp\BuildAgent\ BUILDAGENTNO\Assemblies

    任何一种方式都应该强制构建控制器下载最新的程序集

    【讨论】:

    • 我们的构建控制器每晚都会重新启动,但构建代理尚未重新启动。我将在今晚重新启动我的构建代理,希望这可以解决问题。感谢您的帮助。
    • 不幸的是,这并没有解决问题。感谢您的帮助,您是否有任何可靠的教程来展示如何扩展我可以尝试的代码活动?只是因为有可能我错过了一步。我相当有信心我没有。
    • 嗨,是的,我可以确认它们都存在于构建控制器和构建代理上。所以我认为这可能是我的构建模板 xaml 中的一个参考问题?
    • 是的,我假设是这样,您的 dll 名称中似乎有一个“活动”,但您的命名空间中没有,抱歉很难远程调试,找不到其他突出的内容
    • 没问题很有趣,最后一击,源下的 dll 是最新版本,即与您在开发框中使用相同的版本来更改模板
    【解决方案2】:

    最后,通过使用 TFS 2013 和最新的服务包解决了这个问题。现在加载自定义程序集没有问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-26
      • 1970-01-01
      • 1970-01-01
      • 2013-04-25
      • 1970-01-01
      相关资源
      最近更新 更多