以编程方式使用过滤器构建解

时间:2015-08-12 13:59:41

标签: c# build msbuild

在浏览了整个Google之后,我发现了一种构建解决方案的好方法。但是,我想要构建的解决方案还包含单元测试项目,我不想将其包含在构建中,或者如果我无法阻止它至少将这些二进制文件放在单独的文件夹中。代码如下:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using Microsoft.Build.Evaluation;
using Microsoft.Build.Execution;
using Microsoft.Build.Framework;
using Microsoft.Build.Logging;

public class BuildSolution
{
    private readonly string _solutionPath;
    private readonly string _outputPath = "C:\\Temp\\TestBuild\\";
    public BuildSolution(string solutionPath, string outputPath = null)
    {
        if (!string.IsNullOrEmpty(outputPath))
            _outputPath = outputPath;

        _solutionPath = solutionPath;
        Directory.EnumerateFiles(_outputPath, "*", SearchOption.AllDirectories)
            .Select(x => new FileInfo(x))
            .ToList()
            .ForEach(x => x.Delete());
    }

    public void Build()
    {
        var pc = new ProjectCollection();

        var globalProps = new Dictionary<string, string>()
        {
            { ProjectPropertyNames.Configuration, "Debug" },
            { ProjectPropertyNames.OutputPath, _outputPath },
            { ProjectPropertyNames.EnableNuGetPackageRestore, "true"},
        };

        var targetsToBuild = new[] { "Build" };
        var buildRequest = new BuildRequestData(_solutionPath, globalProps, null, targetsToBuild, null);

        var buildParams = new BuildParameters(pc);
        buildParams.Loggers = new List<ILogger>() { new ConsoleLogger(LoggerVerbosity.Minimal) };
        var buildManager = BuildManager.DefaultBuildManager;
        buildManager.BeginBuild(buildParams);
        var buildSubmission = buildManager.PendBuildRequest(buildRequest);

        buildSubmission.ExecuteAsync(BuildCompleted, null);
        while (!done)
        {
            Thread.Sleep(10);
        }
        buildManager.EndBuild();
        Console.WriteLine("OverallResult:{0}", buildSubmission.BuildResult.OverallResult);

    }
    bool done = false;
    private void BuildCompleted(BuildSubmission submission)
    {
        done = submission.IsCompleted;
    }

    /// <summary>
    /// Unused, but I tried it and it gives me back the correct projects but the build fails because of dependant nuget packages
    /// </summary>
    /// <param name="path">path of solution</param>
    /// <returns></returns>
    private IEnumerable<FileInfo> GetFirstLevelProjects(string path)
    {
        foreach (var dir in Directory.EnumerateDirectories(path))
        {
            foreach (var file in Directory.EnumerateFiles(dir, "*.csproj"))
            {
                if (!file.Contains("Test"))
                    yield return new FileInfo(file);
            }
        }
    }
}
没什么好看的。 (我正在尝试使构建异步,所以我可以更新状态......我们会看到,我可能会将其切换回同步)。我试过的一件事是,不是将解决方案放在构建请求中,而是使用第一级项目构建项目集合(我使用git和子模块,所以我不想构建所有不相关的子项目 - 模块)。这条路线的问题在于构建会因为nuget包而失败(不知道为什么或如何绕过它)。当我构建解决方案时,它成功构建,但我的outputPath还包括测试二进制文件。我的最终游戏是输出可以复制到我的特定文件夹。如果我知道我可以过滤测试项目中的所有二进制文件,我不介意使用测试二进制文件......那么如何?我有什么选择?

1 个答案:

答案 0 :(得分:-1)

为什么不是MsBuild?

我能想到的最简单的方法是使用MsBuild来完成它。

msbuild C:\myFolder\mySolution.sln /p:Configuration=Release

至于不构建测试,现在可以从visual studio中轻松更改

Right Click on Solution > Properties > Configuration Properties (on left side)

从那里你可以切换到发布模式并取消选中测试项目旁边的框。这将告诉visual studio,当它发布版本时,它可以跳过这些项目。

没有MsBuild

但是,如果你想继续以你展示的方式构建它们,我会更改程序集名称(dll名称),以便你可以用你喜欢的脚本语言轻松识别它们。

Right Click on Project > Application Tab (on left side) > Assembly Name Box

我会称他们为SolutionNameSpace.Tests.ProjectUnderTest.dll。 然后,在您的构建过程中,您可以过滤掉SolutionNameSpace.Tests.*.dll。请注意,如果您引用测试库,它们也可以复制到您的输出文件夹中。