C# 如何在新的TeamFoundation 2013模板中获取工作区对象

C# 如何在新的TeamFoundation 2013模板中获取工作区对象,c#,tfs,tfsbuild,C#,Tfs,Tfsbuild,在TeamFoundation 2013默认生成模板的新版本中,缺少工作空间变量。对于一些关键活动,如ConvertWorkspaceItem,它需要作为输入参数。如何获取TfvcTemplate.12.xaml模板的当前工作区?我试图使用,但它对我不起作用(返回空工作区名称)。有什么建议吗?我使用了Microsoft.TeamFoundation.Build.Activities.dll(由Microsoft用于创建工作区名称)中的内部类。您需要使用以下代码创建自定义活动: public se

在TeamFoundation 2013默认生成模板的新版本中,缺少
工作空间
变量。对于一些关键活动,如
ConvertWorkspaceItem
,它需要作为输入参数。如何获取TfvcTemplate.12.xaml模板的当前工作区?我试图使用,但它对我不起作用(返回空工作区名称)。有什么建议吗?

我使用了Microsoft.TeamFoundation.Build.Activities.dll(由Microsoft用于创建工作区名称)中的内部类。您需要使用以下代码创建自定义活动:

public sealed class GetDefaultWorkspace : BaseActivity<Workspace>
{     
    public override Activity CreateBody()
    {
        var type = typeof(TfGetSources).Assembly.GetType("Microsoft.TeamFoundation.Build.Activities.TeamFoundation.TfGetSources+GetDefaultWorkspaceName");

        var activity = (CodeActivity<string>)Activator.CreateInstance(type);
        var sequence = new Sequence();
        var workspaceName = new Variable<string>();

        sequence.Variables.Add(workspaceName);
        sequence.Activities.Add(activity);
        activity.Result = (OutArgument<string>) workspaceName;

        sequence.Activities.Add(new GetWorkspace
            {
                Name = workspaceName,
                Result = new LambdaReference<Workspace>(ctx => Result.Get(ctx))
            });

        return sequence;
    }
}
公共密封类GetDefaultWorkspace:BaseActivity
{     
公共重写活动CreateBody()
{
var type=typeof(TfGetSources.Assembly.GetType(“Microsoft.TeamFoundation.Build.Activities.TeamFoundation.TfGetSources+GetDefaultWorkspaceName”);
var activity=(CodeActivity)Activator.CreateInstance(类型);
变量序列=新序列();
var workspaceName=新变量();
sequence.Variables.Add(工作空间名称);
顺序.活动.添加(活动);
activity.Result=(OutArgument)工作空间名称;
sequence.Activities.Add(新建GetWorkspace
{
名称=工作空间名称,
结果=新的LambdaReference(ctx=>Result.Get(ctx))
});
返回序列;
}
}

2013年有一个名为
GetLocalPath
的新活动取代了ConvertWorkspaceItem。 活动位于
Microsoft.TeamFoundation.Build.Activities
程序集中的
Microsoft.TeamFoundation.Build.Activities.Core
命名空间下

它使用LocalPathProvider类聚合生成中使用的所有工作区,并在一个位置公开所有工作区的路径转换。这基本上消除了了解工作区的依赖性,以便将服务器路径转换为本地路径,并允许您使用任意多的工作区,而无需担心出现问题


当MS拿走某些东西时,通常是有充分的理由的。“黑客”真的没有必要。

我相信这里使用的方法将使用已经下载的工作区。请记住,这种方法只能在Try Compile、Test、Publish的finally语句中的“Initialize Environment”之后和ResetEnvironment之前的“Run on agent”序列的范围内工作。否则,工作流将不知道源目录


这个答案可能对某些人更有效。ghord的答案很有效,并将工作区传递回可以在XAML中使用的位置。然而,出于我的目的,我只想在我的自定义TFS活动中使用工作区,所以我最终选择了这个替代方案

public sealed class CustomActivity : CodeActivity
{
    protected override void Execute(CodeActivityContext context)
    {
        // get workspace
        var buildDetail = context.GetExtension<IBuildDetail>();
        var buildAgent = context.GetExtension<IBuildAgent>();
        var buildDirectory = buildAgent.GetExpandedBuildDirectory(buildDetail.BuildDefinition);
        var workspacePath = Path.Combine(buildDirectory, "src");
        var wsInfo = Workstation.Current.GetLocalWorkspaceInfo(workspacePath);
        var tfs = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(wsInfo.ServerUri);
        tfs.Connect(ConnectOptions.None);
        var vcs = tfs.GetService<VersionControlServer>();

        // finally can get to the workspace here
        var workspace = vcs.GetWorkspace(workspacePath);
    }
}
公共密封类CustomActivity:CodeActivity
{
受保护的覆盖无效执行(CodeActivityContext上下文)
{
//获取工作区
var buildDetail=context.GetExtension();
var buildAgent=context.GetExtension();
var buildDirectory=buildAgent.GetExpandedBuildDirectory(buildDetail.BuildDefinition);
var workspacePath=Path.Combine(buildDirectory,“src”);
var wsInfo=Workstation.Current.GetLocalWorkspaceInfo(工作空间路径);
var tfs=tfstreamprojectcollectionfactory.GetTeamProjectCollection(wsInfo.ServerUri);
tfs.Connect(ConnectOptions.None);
var vcs=tfs.GetService();
//终于可以到这里的工作区了
var workspace=vcs.GetWorkspace(workspacePath);
}
}

使用此方法,我不必让一个活动只返回工作区,然后将工作区传递给其他TFS活动。我只是在活动运行时从自己的活动中获取工作区。

获取本地路径的正确方法。如果我想在构建过程中签出一些文件怎么办?如果我没记错的话(自从我浏览了那个IL之后的一段时间)只要您使用这些活动执行“手动”get,还可以添加它们对GetLocalPath的映射。请确保您意识到这是工具箱中的一个新活动-您不能直接调用该方法。请注意,TFS 2013已在Try Compile、Test和Publish序列的最后部分添加了ResetEnvironment任务。编译后,将清除在此重置任务之前初始化的任何变量。这花费了我三天的时间试图弄清楚为什么我会遇到null引用异常。