James Monger
James Monger

Reputation: 10675

$(ProjectDir) prebuild event macro incorrect

I am using Visual Studio 2017 and I have a pre-build event.

I have a project located at C:\Project\src\Project\, with a batch file doSomething.bat at C:\Project\src\Project\doSomething.bat.

In my pre-build event, I want to run doSomething.bat, so I have this script:

cd $(ProjectDir) && call ./doSomething.bat

However, $(ProjectDir) actually places me in C:\Project\src\Project\bin\Debug\netcoreapp1.1\

This is not what the documentation states. How can I fix this?

Upvotes: 2

Views: 3933

Answers (3)

SteveCinq
SteveCinq

Reputation: 1963

I had this happen after I'd manually edited the project file.

I'd inadvertently moved this line:

<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

to below the <PropertyGroup><PreBuildEvent> ... elements from its original position above them.

Try this:

  1. Open your project file, eg MyProject.csproj (or MyProject.vbproj).
  2. Find <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> (or <Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />).
  3. Move it to directly above the beginning of your build event elements (<PropertyGroup><PreBuildEvent> ...)
  4. Clean the project/solution, recompile and you should be good.

Note: I also had another project that had this error out of the box so I think it can "just happen" as well.

Upvotes: 1

Alex Klaus
Alex Klaus

Reputation: 8954

There is a workaround on how to make it resolve common macros and properties correctly (discussed on the thread, mentioned by @MartinUllrich).

See an example on the link. The key points of the solution is to modify the .csproj file so:

  • The root tag stays without attributes: just <Project> rather than <Project Sdk="Microsoft.NET.Sdk">
  • Import Sdk.props at the beginning: <Import Sdk="Microsoft.NET.Sdk.Web" Project="Sdk.props" />
  • Import Sdk.targets before pre-, post- build events: <Import Sdk="Microsoft.NET.Sdk.Web" Project="Sdk.targets" />

Upvotes: 2

Martin Ullrich
Martin Ullrich

Reputation: 100741

For SDK-based projects PreBuildEvent and PostBuildEvent are evaluated too early to receive "final" values for a lot of properties, they are even considered to be deprecated (see https://github.com/dotnet/project-system/issues/1569)

As a quick workaround, you can use $(MSBuildProjectDirectory) or $(MSBuildThisFileDirectory) which will give you the directory that the .csproj file is in.

For a more integrated solution, you can add a custom target to the csproj file like this (no cd step needed):

<Target Name="MyAfterBuild" AfterTargets="Build">
  <Exec Command="test.bat" />
</Target>

Upvotes: 7

Related Questions