Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Visual Studio add pre-build event that always runs (C# project)

In my project, I am running an external tool to update some binary files. These files are included in the project as "content".

At the moment the tool is set to run during "pre-build event" in C# project properties. Unfortunately, this event is only executed if the project is out of date, which is not what I need.

I am working around this by always using "rebuild" instead of "build" on my project, but this is tedious and slow.

I need to execute this tool always, irrespective of whether a project is or is not up to date. Actually, even before MSBuild even determines whether the project is up-to-date, because the tool modifies some of the files included in the project, therefore affecting the up-to-date check result.

Is there a proper way to do it?

like image 682
kaalus Avatar asked Mar 07 '15 15:03

kaalus


People also ask

What is PostBuildEvent?

PostBuildEvent. This event executes after the build finishes.

What is PreBuild and PostBuild?

PreBuild and PostBuild aren't only used for hiding or unhiding pages. The main difference really is that PreBuild fires before any peoplecode code event on all the rows and fields in the component such as FieldDefault and RowInit. PostBuild runs after that.

How do I run a batch file in post build event?

If you go to the Properties page for your project, you should select the Build Events tab. You can type in the call to your batch file in the Post-build event command line text box. If you want to refer to the batch file using the paths included in the project or solution, you can click on the Edit Post-Build...

How do I open a build event in Visual Studio?

In Solution Explorer, select the project for which you want to specify the build event. On the Project menu, click Properties. Select the Build Events tab.


4 Answers

Here's the solution. Define this property in your project file:

<PropertyGroup>
    <DisableFastUpToDateCheck>true</DisableFastUpToDateCheck>
</PropertyGroup> 

PreBuildStep will then execute every time, regardless of whether the project is or isn't up to date.

It seems that Visual Studio is bypassing normal up-to-date checks of MSBuild and using some sort of custom check that is faster, but has a side effect of breaking customized build targets.

like image 83
kaalus Avatar answered Oct 22 '22 09:10

kaalus


In project level, you have three options:

1) Pre-build action

<PropertyGroup>
  <PreBuildEvent>notepad.exe Foo.txt</PreBuildEvent>
</PropertyGroup>

2) normal BeforeBuild target

<Target Name="BeforeBuild">
  <Exec Command="notepad.exe Foo.txt" />
</Target>

3) "attached" to "Build" target (like stijn suggested)

<Target Name="BeforeBuild2" BeforeTargets="Build">
  <Exec Command="notepad.exe Foo.txt" />
</Target>

Actually this solution (in case of Build) will not work, because DependsOnTargets is executed BEFORE BeforeTargets. And exactly in DependsOnTargets the real (CoreBuild) sits :) This is why they invented the 'BeforeBuild' target ;)


In both cases VS check if something is changes (files are up-to-date). Why do you even want to run external program if nothing was changed? If this program work on file (eg. "content") msbuild and VS should detect files as out-of-date and process building.


Unfortunately IDE (Visual Studio) has it's own method to deal with msbuild projects. The main mechanism is the same, but when it's came to determine what project build or not, or in which order... VS act totalny different.

You can use external tool and run "msbuild" against your solution or project. This will also compile "the proper way" and binaries will be not different, but you will have full capabilities and potentials of MsBuild

like image 31
Carnifex Avatar answered Oct 22 '22 07:10

Carnifex


There is also one additional pre build event that was not discussed here. Usually code analyzers are using that to check if code analyzer was downloaded by NuGet.

So if you want to execute something before code analyzers you need to use that target.

You just need to add <Target/> node under <Project/> node in your .csproj file:

<Target Name="DownloadNugetPackages" BeforeTargets="PrepareForBuild">
    <Exec Command="notepad.exe Foo.txt"/>
</Target>

PrepareForBuild event will run before pre build events.

like image 29
Shoter Avatar answered Oct 22 '22 07:10

Shoter


None of these solutions worked for me using Visual Studio for Mac. I want to run a bash script before building the project but since I'm using Xamarin, some things are getting out of whack. I tried all different types of targets and even tried the CustomCommands in the project options but still I would get issues around MSbuild just running automatically or not truly running before the build

You can run the PreBuild events in a separate project that compiles before your main project.

  1. Create a new project and name it something like "PreBuildEvent"
  2. Add your MSbuild targets/commands as shown above to this new PreBuildEvent.csproj file for each property group/build configuration
  3. In the project where you originally to do the PreBuild work, add a reference to this new project.
  4. This new project will build first, executing any PreBuild events, and once this project is built, it will kick off the build for your original project. This is because when you add a reference to a project, visual studio makes sure to build them in the correct order
like image 43
stepheaw Avatar answered Oct 22 '22 08:10

stepheaw