将Postbuild事件添加到项目中

将Postbuild事件添加到项目中

问题描述:

当我生成C#项目(csproj文件)并编译它时,msbuild以某种方式无法识别前和后生成事件中的变量$(ConfigurationName)$(ProjectDir)(和其他)。将Postbuild事件添加到项目中

当我手动将生成的.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元素之后结束?

很显然,我目前使用从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文件。调试文件
  • 添加postbuildevent:copy "$(ProjectDir)app.config.$(ConfigurationName)" "$(TargetDir)\$(ProjectName).exe.config
  • 看到项目的建立和正确的配置文件被应用
  • 使用记事本(这样不会留下任何痕迹)
  • 运行示例项目
  • 刷新和删除建设前和postbuild事件您创建的项目。
  • 输出窗口会说,如果加入他们The system cannot find the file specified.
+0

似乎文件'app.config.'不存在(它缺少'ConfigurationName')。什么是您的手动构建事件? – 2014-08-29 12:09:21

+0

不分析$(ConfigurationName)。如果我将项目文件中的buildevents移动到其中, – Alfons 2014-08-29 12:12:10

+0

猜测其中一个Imports负责设置变量,我搞砸了一个项目文件。在此之后,我必须拥有后期构建事件:或变量为空。你可以添加构建事件的方式让他们在底部? – Adam47 2014-08-29 12:46:08

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

谢谢!完美的作品。 – Alfons 2014-09-04 14:05:19

项目相关的宏不被解析项目实际建造之前(构建项目包括添加引用)。除了使用$(ProjectName)的,路径可以使用解变量(已经存在)这样构成:

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

注意,项目名是项目硬编码的实际名称,但因为你生成一个项目这应该很容易添加。

+0

这可能是一个有用的解决方法。 – Alfons 2014-09-01 12:54:04