简体   繁体   English

将Postbuild事件添加到项目中

[英]Adding a Postbuild event to a project

When I generate a C# project ( csproj file) and then compile it, msbuild somehow doesn't recognize the variables $(ConfigurationName) and $(ProjectDir) (and others) in the pre- and postbuild event. 当我生成一个C#项目( csproj文件)然后编译它时, msbuild以某种方式无法识别pre-andbuild事件中的变量$(ConfigurationName)$(ProjectDir) (和其他)。

When I Manually move the pre- and postbuild event configuration in the generated .csproj file further downwards, then msbuild recognizes these variables correctly. 当我手动将生成的.csproj文件中的pre-andbuild事件配置进一步向下移动时,msbuild会正确识别这些变量。

Adding the buildevent to the project is the last thing I do before saving the project. 在保存项目之前,我最后要做的就是将构建添加到项目中。

This is how I add it: 这就是我添加它的方式:

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);
}

The error I get when running the generated project through msbuild is this: 通过msbuild运行生成的项目时得到的错误是这样的:

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

When I then manually edit the .csproj file (with notepad or another text editor), cut the pre-and postbuild event, and paste it below the <Import Project="$(MSBuildToolsPath)\\Microsoft.CSharp.targets" /> element, then msbuild builds the generated .csproj file fine. 然后,当我手动编辑.csproj文件(使用记事本或其他文本编辑器)时,剪切pre-andbuild事件,并将其粘贴到<Import Project="$(MSBuildToolsPath)\\Microsoft.CSharp.targets" />元素下面,然后msbuild构建生成的.csproj文件。

What is the best way to add the build events to the .csproj file so it ends up after the Import element in the resulting XML ? 将构建事件添加到.csproj文件的最佳方法是什么,以便在生成的XMLImport元素之后结束?

Apparently, my current way of using [ProjectPropertyGroupElement][1] by requesting it from AddPropertyGroup of the the Xml property of the Microsoft.Build.Evaluation.Project is not. 显然,我目前使用[ProjectPropertyGroupElement][1]的方法是从Microsoft.Build.Evaluation.ProjectXml属性的AddPropertyGroup请求它不是。

Example Project: 示例项目:

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();
    }
}

Steps to reproduce 重现步骤

  • Create a new project 创建一个新项目
  • Manually add app.config.debug file which should be different to the app.debug file 手动添加app.config.debug文件,该文件应与app.debug文件不同
  • Add the postbuildevent: copy "$(ProjectDir)app.config.$(ConfigurationName)" "$(TargetDir)\\$(ProjectName).exe.config 添加postbuildevent: copy "$(ProjectDir)app.config.$(ConfigurationName)" "$(TargetDir)\\$(ProjectName).exe.config
  • See that the project build and the correct config file is applied 看到项目构建和正确的配置文件已应用
  • Remove the pre- and postbuild events using notepad (so not to leave any traces) 使用记事本删除预建和事后事件(不要留下任何痕迹)
  • Run the example project 运行示例项目
  • Reload and build the project you created. 重新加载并构建您创建的项目。
  • Output window will now say The system cannot find the file specified. 输出窗口现在说The system cannot find the file specified.
var propertyGroupElement = project.Xml.CreatePropertyGroupElement();
project.Xml.AppendChild(propertyGroupElement);
propertyGroupElement.AddProperty(PreBuildEventFixture, PreBuildEvent);
propertyGroupElement.AddProperty(PostBuildEventFixture, PostBuildEvent);

Project related macros are not parsed if they are added before the project is actually constructed (constructing a project includes adding references). 如果在实际构建项目之前添加项目相关宏(构建项目包括添加引用),则不会解析项目相关宏。 Instead of using $(ProjectName) , the path can be constructed using solution variables (that already exist) like this : 可以使用解决方案变量(已经存在)构建路径,而不是使用$(ProjectName) ,如下所示:

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

Note that ProjectName is the actual name of the project hardcoded, but since you are generating a project this should be easy to add. 请注意,ProjectName是硬编码项目的实际名称,但由于您要生成项目,因此应该很容易添加。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM