将Visual Studio解决方案的输出构建顺序输出到文本文件

11
有没有办法通过命令行将构建顺序输出到文本文件?
为了说明:我们使用多个源代码分支,并且每个分支都有包含100多个项目的大型解决方案。我需要编写构建脚本以从命令行构建这些解决方案。然后,我们可以根据团队正在处理的项目仅为分支上的项目引用调整解决方案。这应该大大增加解决方案加载时间并减轻开发人员和我自己的沮丧感,我希望如此 :)
我将继续寻找,可能会考虑使用C#和与VS提供的API。我们正在使用2012更新1版本。

你能否重新构建一下,复制编译器的输出并进行处理?我手头没有 Visual C# 来查看是否可行。 - congusbongus
是的,那会起作用。我可以将详细程度设置为最小,并获取输出并解析项目名称。但我希望有一种更优雅和可重复解决此问题的方法,因为这可能是我们将来需要重复执行的任务。 - mikeyg
构建顺序由存储在解决方案文件中的项目依赖关系定义。如果您想自己获取构建顺序,需要分析解决方案文件和项目依赖关系。 - Jehof
2
假设项目A和项目B之间没有依赖关系,编译器当前按照任意顺序A、B进行构建。如果后来有人引入了依赖关系,使得A现在依赖于B,包含所有项目的解决方案将会"正常运行"并重新排序构建。但是,当然,您的命令行构建不会这样做,每次构建A都将基于一个稍旧的B构建版本。 - Damien_The_Unbeliever
Damien,我想这是需要牢记的一点。我们之前有一个使用命令行构建的版本。当依赖项发生变化时,改变依赖项的人就需要修改构建脚本。然而,如果下面的插件思路可行,我可以在CI环境中添加一个任务来重新生成构建顺序并与现有列表进行比对。这样,如果构建顺序发生了改变或需要更新,CI任务就会失败。 - mikeyg
2个回答

8
这是一个很好的 Visual Studio 插件项目候选项。
步骤如下:
1. 创建一个新的 Visual Studio Add-in 项目。 2. 在项目创建向导中,确保您在“选择 Add-in 选项”步骤中选择以下配置(其他步骤不重要,假设您将使用 C#): enter image description here
  1. In the Connect.cs file, add the following fields:

    private BuildEvents _buildEvents;
    private Events _events;
    private bool buildEventConnected = false;
    
  2. And add / modify these methods accordingly:

    public void OnConnection(object application, ext_ConnectMode connectMode, object addInInst, ref Array custom)
    {
        _applicationObject = (DTE2)application;
        _addInInstance = (AddIn)addInInst;
        _events = _applicationObject.Events;
        _buildEvents = _events.BuildEvents;
    
        if (connectMode != ext_ConnectMode.ext_cm_UISetup && !buildEventConnected)
        {
            _buildEvents.OnBuildDone +=
                new _dispBuildEvents_OnBuildDoneEventHandler(BuildEvents_OnBuildDone);
            buildEventConnected = true;
        }
    }
    
    private void BuildEvents_OnBuildDone(vsBuildScope Scope, vsBuildAction Action)
    {
        const string BUILD_OUTPUT_PANE_GUID = "{1BD8A850-02D1-11D1-BEE7-00A0C913D1F8}";
        TextDocument txtOutput = default(TextDocument);
        TextSelection txtSelection = default(TextSelection);
        Window vsWindow = default(Window);
        vsWindow = _applicationObject.Windows.Item(EnvDTE.Constants.vsWindowKindOutput);
        OutputWindow vsOutputWindow = default(OutputWindow);
        OutputWindowPane objBuildOutputWindowPane = default(OutputWindowPane);
        vsOutputWindow = (OutputWindow)vsWindow.Object;
        foreach (OutputWindowPane objOutputWindowPane in vsOutputWindow.OutputWindowPanes)
        {
            if (objOutputWindowPane.Guid.ToUpper() == BUILD_OUTPUT_PANE_GUID)
            {
                objBuildOutputWindowPane = objOutputWindowPane;
                break;
            }
        }
        txtOutput = objBuildOutputWindowPane.TextDocument;
        txtSelection = txtOutput.Selection;
        txtSelection.StartOfDocument(false);
        txtSelection.EndOfDocument(true);
        objBuildOutputWindowPane.OutputString(System.DateTime.Now.ToString());
        txtSelection = txtOutput.Selection;
        var solutionDir = System.IO.Path.GetDirectoryName(_applicationObject.Solution.FullName);
        System.IO.File.WriteAllText(solutionDir + "\\build_output.log", txtSelection.Text);
    }
    
    public void OnDisconnection(ext_DisconnectMode disconnectMode, ref Array custom)
    {
        if (buildEventConnected)
        {
            _buildEvents.OnBuildDone -= new _dispBuildEvents_OnBuildDoneEventHandler(BuildEvents_OnBuildDone);
            buildEventConnected = false;
        }
    }
    

完成以上步骤后,每次构建时,您的输出都会发送到解决方案文件夹中的build_output.log文件中。


会尝试使用这个插件。需要一些时间来测试,自从2008年以来就没有构建过插件了,当时似乎很复杂!测试结果后再回来!谢谢! - mikeyg
Alex,非常感谢你的代码。这正是我在寻找的东西。我稍微调整了一下,现在有更多的想法了(你为我打开了潘多拉魔盒!)。 - mikeyg
还有没有办法在像VS2017这样的新版本的VisualStudio中实现这个? - Epligam

7
快速的方法是执行“清理解决方案”,这样你就可以在构建日志中看到倒置的顺序。

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