创建一个 NuGet 包,用于更新 MSBUILD 进程以在生成目标之前运行程序



>我正在尝试创建一个在生成之前运行外部应用程序的NuGet包。该应用程序创建一个compilationtime.h文件,以了解编译时间,以便在">关于"对话框中显示该文件。

我的 NuGet 包有一个包含CreateCompilationTimeFile的工具文件夹.exe以及一个包含{packagename}.props文件的生成文件夹。

我已经尝试了很多组合来在{packagename}.props文件中创建预构建事件,但没有一个有效。

我试过这个:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemDefinitionGroup>
<PreBuildEvent>
<Command>"$(MSBuildThisFileDirectory)..toolsCreateCompilationTimeFile.exe"</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
</Project>

还有这个:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="BeforeBuild2" BeforeTargets="Build">
<Exec Command="$(MSBuildThisFileDirectory)..toolsCreateCompilationTimeFile.exe"/>
</Target>
</Project>

如果我在没有 NuGet 包的情况下执行此操作,并且使用下一个属性表执行此操作,则它可以正常工作:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets" />
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<ItemDefinitionGroup>
<PreBuildEvent>
<Command>"$(SolutionDir)ToolsCreateCompilationTimeFile.exe"</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemGroup />
</Project>

但我想使用 NuGet 包而不是属性表来执行此操作。

我做错了什么? 谢谢。

正如 @leo-liu-msft 所说,第二个解决方案有效,但它没有按预期工作,我将在下面解释。

如果{packagename}.props包含以下内容:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="CreateCompilationFileTimeTarget" BeforeTargets="Build">
<Exec Command="$(MSBuildThisFileDirectory)..toolsCreateCompilationTimeFile.exe"/>
</Target>
</Project>

假设您刚刚创建了一个全新的C++项目,并在其中一个.cpp文件中包含compilationtime.h文件:

#include "compilationtime.h"

请记住,该项目是新的,您没有任何compilationtime.h文件喷射,由于 {packagename}.props,它应该构建过程之前创建。

如果生成C++项目,将收到C0183 无法打开包含文件:"编译时间.h":没有此类文件或目录错误。

如果随后打开项目文件夹,则编译时间.h文件不在它应该的位置。

现在注释#include "compilationfile.h"行并再次编译。编译器将完成没有任何错误,如果您分析文件夹,文件将在那里!

现在您的compilationfile.h已经存在,请对其进行编辑并将tm_year更改为 0,例如:

#pragma once
static struct tm GetCompilationTime()
{
struct tm compilationTime = { 0 };
compilationTime.tm_year=0;
compilationTime.tm_mon=9;
compilationTime.tm_mday=15;
compilationTime.tm_hour=15;
compilationTime.tm_min=37;
compilationTime.tm_sec=41;
return compilationTime;
}

..然后在.cpp文件中,将年份打印到控制台:

#include "pch.h"
#include <iostream>
#include "CompilationTime.h"
int main()
{
std::cout << GetCompilationTime().tm_year << std::endl;
}

编译并运行程序。程序将打印 0而不是当前年份,但是如果您打开compilationtime.h文件,它会使用当前年份进行修改,因此编译器的行为就像我们配置AfterTargets="Build"BeforeTargets="Build"而不是我们配置的 。

最后,我解决了将BeforeTargets更改为PrepareForBuild的问题,如下所示:

<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="CreateCompilationFileTimeTarget" BeforeTargets="PrepareForBuild">
<Exec Command="$(MSBuildThisFileDirectory)..toolsCreateCompilationTimeFile.exe"/>
</Target>
</Project>

现在它总是在构建之前根据需要创建/更新编译时间.h文件。

最新更新