将后期生成事件添加到项目

本文关键字:添加 项目 事件 | 更新日期: 2023-09-27 18:20:08

当我生成一个 C# 项目(csproj文件(然后编译它时,msbuild不知何故无法识别$(ConfigurationName)$(ProjectDir)(以及其他(在构建前和构建后事件中的变量。

当我手动将生成的.csproj文件中的生成前和构建后事件配置进一步向下移动时,msbuild 会正确识别这些变量。

将 buildevent 添加到项目中是我在保存项目之前做的最后一件事。

这是我添加它的方式:

using Microsoft.Build.Construction;
using Microsoft.Build.Evaluation;
private const string PreBuildEventFixture = "PreBuildEvent";
private const string PostBuildEventFixture = "PostBuildEvent";
private const string PreBuildEvent = "attrib -R '"$(ProjectDir)app.config'"";
private const string PostBuildEvent = "copy '"$(ProjectDir)app.config.$(ConfigurationName)'" '"$(TargetDir)''$(ProjectName).dll.config'" 'r'n attrib -R '"$(ProjectPath)'"";
public void AddBuildEvents(Project project)
{
    ProjectPropertyGroupElement propertyGroupElement = project.Xml.AddPropertyGroup();
    propertyGroupElement.AddProperty(PreBuildEventFixture, PreBuildEvent);
    propertyGroupElement.AddProperty(PostBuildEventFixture, PostBuildEvent);
}

通过 msbuild 运行生成的项目时遇到的错误是:

The command "copy "app.config." "'.dll.config"" exited with code 1

然后,当我手动编辑.csproj文件(使用记事本或其他文本编辑器(时,剪切构建前和构建后事件,并将其粘贴到 <Import Project="$(MSBuildToolsPath)'Microsoft.CSharp.targets" /> 元素下方,然后 msbuild 可以很好地构建生成的.csproj文件。

将构建事件添加到.csproj文件以便它最终位于生成的XML中的Import元素之后的最佳方法是什么?

显然,我目前使用[ProjectPropertyGroupElement][1]的方式是通过从 Microsoft.Build.Evaluation.Project 的 Xml 属性的 AddPropertyGroup 请求它。

示例项目:

using System.IO;
using Microsoft.Build.Construction;
using Microsoft.Build.Evaluation;
class Program
{
    private const string PreBuildEventFixture = "PreBuildEvent";
    private const string PostBuildEventFixture = "PostBuildEvent";
    private const string PreBuildEvent = "attrib -R '"$(ProjectDir)app.config'"";
    private const string PostBuildEvent = "copy '"$(ProjectDir)app.config.$(ConfigurationName)'" '"$(TargetDir)''$(ProjectName).exe.config'" 'r'n attrib -R '"$(ProjectPath)'"";
    private const string ProjectFile = @"C:'test'TestProject'TestProject.csproj";
    static void Main(string[] args)
    {
        if (!File.Exists(ProjectFile))
            throw new FileNotFoundException("ProjectFile not found");
        ProjectCollection collection = new ProjectCollection();
        Project project = collection.LoadProject(ProjectFile);
        ProjectPropertyGroupElement propertyGroupElement = project.Xml.AddPropertyGroup();
        propertyGroupElement.AddProperty(PreBuildEventFixture, PreBuildEvent);
        propertyGroupElement.AddProperty(PostBuildEventFixture, PostBuildEvent);
        project.Save();
        collection.UnloadAllProjects();
    }
}

重现步骤

  • 创建新项目
  • 手动添加 app.config.debug 文件,该文件应与 app.debug 文件不同
  • 添加后期构建事件:copy "$(ProjectDir)app.config.$(ConfigurationName)" "$(TargetDir)'$(ProjectName).exe.config
  • 查看项目生成并应用了正确的配置文件
  • 使用记事本删除生成前和生成后事件(以免留下任何痕迹(
  • 运行示例项目
  • 重新加载并生成您创建的项目。
  • 输出窗口现在将显示The system cannot find the file specified.

将后期生成事件添加到项目

var propertyGroupElement = project.Xml.CreatePropertyGroupElement();
project.Xml.AppendChild(propertyGroupElement);
propertyGroupElement.AddProperty(PreBuildEventFixture, PreBuildEvent);
propertyGroupElement.AddProperty(PostBuildEventFixture, PostBuildEvent);

如果在实际构造项目之前添加与项目相关的宏(构造项目包括添加引用(,则不会分析这些宏。不使用$(ProjectName),可以使用解变量(已经存在(构造路径,如下所示:

copy "$(SolutionDir)ProjectName'app.config.$(Configuration)" "$(SolutionDir)ProjectName'bin'$(Configuration)'ProjectName.dll.config"

请注意,ProjectName 是硬编码项目的实际名称,但由于您正在生成项目,因此应该很容易添加。