0

Given, a package file called example:

<?xml version="1.0" encoding="utf-8"?>
<package>
    <metadata>
        <id>example</id>
        <version>$version$</version>
        <title>$title$</title>
        <authors>$author$</authors>
        <requireLicenseAcceptance>false</requireLicenseAcceptance>
        <description>$description$</description>
        <copyright>$copyright$</copyright>
    </metadata>
    <files>
        <file src="example.targets" target="build" />
        <file src="example.props" target="build" />
    </files>
</package>

When is example.targets and example.props consumed?

Originally I thought it was only during the build process for the project that is using the Nuget package.

But it seems to use props files on installation?

I'm using old-style packages.config in my consuming projects.

Anyone point me to details on this or advise. Thankyou.

1 Answers1

1

Just as this document said,

.props is added at the top of the project file; .targets is added at the bottom.

example.props will be read first when you install the nuget package into your project.

Therefore, properties will be available at the start of the build process.

It is usually used to define new global properties, or several new items which can include some files into your project. Properties and items will be executed at this moment.

example.targets will be read when you build the project with the installed nuget package.

Nuget will import .props file very early in Microsoft.Common.props.

And the principle is actually the same as described in this document.

In more detail, when you install a nuget package in the project, nuget will read the csproj file(add the reference node into csproj file).

Because when a nuget is installed, it will read a part of the csproj file, and only the content of the header part will be read, such as Microsoft.Common.props file, and the .props file is imported before it. So when you install the nuget package, the .props file will be read in its entirety, so any xml node of its content will be read and executed first.

Therefore, it will work when you install the nuget package.

However, .targets will be imported at the bottom of the csproj file. So when the nuget package is installed, it cannot reach there and the file cannot be read at all, so the file will only be read when the project is built.

In fact, .props file is read twice. One time is when nuget was installed, and another time is when you are building the project, but .targets can only be read when building the project.

Update 1

Note:

For the target of MSBuild, it is special. Some tasks like copy task are written under a target. But if you execute a target with .props or .targets, you should execute the build process. So if you want to the target to be executed under installation process of nuget package, it obviously doesn't work. And you should execute build process to execute it. And when you install the nuget package, it will not execute the build process.

So as I said before, .props and .targets are the same when you use a target. When MSBuild reads the .props or .targets and enter the target, since the condition is like BeforeTargets="Build", however, it is under installation process rather than build process so far. And BeforeTargets="Build" needs build process. So it will skip it.

This happens 'once' means msbuild reads the file first under the nuget installation process. It will get the properties or items which can include some files into your main project. But target depends on the build process, so MSBuild will skip it under the nuget installation process(which not execute the build yet).

Mr Qian
  • 21,064
  • 1
  • 31
  • 41
  • Just for clarification, in the document, it just suggests that it adds the props file to the project. So what do you mean when you say "Will work when you install"? Many thanks. – Gregory William Bryant Oct 09 '20 at 09:17
  • `.props` file is imported before `Microsoft.Common.props` while `.targets` is imported at the bottom of the csproj file. When you install a nuget package(it will read part of the csproj file and add reference node into `csproj`). So only the top is read by the nuget package. However, `.props` file is imported before the header `Microsoft.Common.props`, so it will be read first when you install the nuget package. – Mr Qian Oct 09 '20 at 09:52
  • I have updated my answer with more detailed info. You can check it. Hope it could help you understand it better:) – Mr Qian Oct 09 '20 at 09:52
  • @PerryQain-MSFT - Thank you for the detailed answer, although I am still stuck on your definition of 'Will work when you install" Does this mean if you put any tasks in your Props file the will run during the Nuget install process? Is there any benefits from props file being available during the install process, or is this just a side-effect of how it updates the csproj file? My limited understanding is that it just renders any properties defined early on the build process so they can be consumed by targets later in the build process? – Gregory William Bryant Oct 11 '20 at 18:21
  • `.props` file are used for defining new properties or items(more likely to global variables) so that they can be got during the whole process while `.targets` file are used for overwriting known properties and operations. If you just define some properties or items to include some files, using `.props` file will import them without build process. If you use tasks with target, its running order depends on the target it depends on rather than the specificity of this file. – Mr Qian Oct 12 '20 at 08:23
  • For an example, if you have a target that depends on Build like ``, it depends on the build process. And it is not related with the particularity of the `.props` and `.targets` files .And as far as I know, if you use targets, you must execute the build process if you want to run them. – Mr Qian Oct 12 '20 at 08:26
  • And the dependent targets are the content of the build process, so when you use the target, you must start the build process, and it has nothing to do with the `.props` and `.targets` files. For other contents of msbuild except target like properties or items, you can use the particularity of the `.props` and `.targets` files. – Mr Qian Oct 12 '20 at 08:30
  • To be more specific, when using properties or items, you can use the particularity of the `.props` and `.targets` files as you want. And if you use targets, it is the same with `.props` and `.targets` files. And it depends on the build button. – Mr Qian Oct 12 '20 at 08:33
  • @GregoryWilliamBryant, any update about this issue? If my answer helps you handle the issue, please do not forget to accept it. And if not, please feel free to let us know:) – Mr Qian Oct 13 '20 at 02:43
  • Thank you for the additional information. For context, I have extended my build process with '.Prop' and '.Target' files successfully - my sticking point is understanding when you say - "Therefore, it will work when you install the NuGet package". The statement implies you can use the props file for 'something' during the NuGet install process. For example, I have targets file currently that copies certain files to my build output process. – Gregory William Bryant Oct 13 '20 at 09:25
  • This happens 'once' when built and not on any subsequent builds. Is it possible to move this to Nuget install/update/restore steps? Hence trying to understand your original statement. – Gregory William Bryant Oct 13 '20 at 09:25
  • 1
    copy task are written under a target. But if you execute a target with `.props` or `.targets`, you should execute the build process. So if you want to the target to be executed under installation process of nuget package, it obviously doesn't work. And you should execute build process to execute it. And when you install the nuget package, it will not execute the build process. – Mr Qian Oct 13 '20 at 09:42
  • So as I said before, `.props` and `.targets` are the same when you use a target. When msbuild reads the `.props` or `.targets` and enter the target, since the condition is like `BeforeTargets="Build"`, however, it is under installation process rather than build process. And `BeforeTargets="Build"` needs build process. So it will skip it. – Mr Qian Oct 13 '20 at 09:45
  • That makes sense, but can you clarify if you can do anything with the props file, or should the sentence - "Therefore, it will work when you install the NuGet package." actually be "Therefore, properties will be available at the start of the build process." – Gregory William Bryant Oct 13 '20 at 09:45
  • `This happens 'once'` means msbuild reads the file first under the nuget installation process. It will get the `properties` or `items` which can include some files into your main project. But target depends on the build process so msbuild will skip it under the nuget installation process(which not execute the build yet). – Mr Qian Oct 13 '20 at 09:51
  • And if you want to copy these files during nuget installation, you should not use the target. And you can [use powershell script](https://stackoverflow.com/questions/20759795/nuget-copy-and-add-files-to-solution-level/20914484). See [this official document](https://learn.microsoft.com/en-us/nuget/create-packages/creating-a-package#from-a-convention-based-working-directory). – Mr Qian Oct 13 '20 at 09:51
  • I think we stretching the limits of StackOverflow comments - is there discord? -The power shell script is not run when NuGet is restored outside of visual studio from my understanding. Can I use Props to add other elements to my project file then, this is the bit I'm confused on. Sorry for the back and forth! – Gregory William Bryant Oct 13 '20 at 09:55
  • :) ha-ha. It doesn't matter:) using powershell is a suggestion and sorry for that I am not familiar with that. For `.props` file, If you add some global properties or items, it is okay and you can use these under `.props` file during nuget installation. Also, the target also can be written there and it is just that you need to click build to execute that. That is enough and might not be complex. I have updated my answer and you can check it:) – Mr Qian Oct 13 '20 at 10:07