NuGet post build step

Sep 1, 2014 at 3:09 PM
The NuGet package currently adds lines to the project post build event. Some of these values are are set to local folder where the project exists.

So when I try to build this project on my build server I get an error because this location does not exist on the server.

The command "xcopy "<mylocalfolder>\packages\Excel-DNA.0.32.0\tools\ExcelDna.xll" "C:\Builds\1\Insight\Pricing Platform Main\bin\Mixed Platforms\Debug\MyProject-AddIn.xll*" /C /Y ...... exited with code 3

Having a look at the install.ps1 I think it is because it uses ${toolMacro}.

As a workaround I can change my post build event to use $(SolutionDir) instead, but if I updated my NuGet package this is going to get replaced.

I think however there might be a better way (since I had this problem recently myself). In NuGet 2.5 they introduced the automatic import of msbuild targets and props files.

If you put the following in a file called build\Excel-DNA.targets it will place the xll and dna file in the bin folder for you:
<Project xmlns="">
        <ExcelDnaFile Include="$(TargetDir)$(TargetName)-AddIn.dna" />
        <ExcelDnaXllFile Include="$(SolutionDir)packages\Excel-DNA.0.32.0\tools\ExcelDna.xll" />
        <ExcelDnaExeFile Include="$(SolutionDir)packages\Excel-DNA.0.32.0\tools\ExcelDnaPack.exe" />
    <Target Name="PricingPlatformNuGetTarget" AfterTargets="Build">
        <Copy SourceFiles="@(ExcelDnaFile)" DestinationFiles="$(TargetDir)$(TargetName)-AddIn64.dna" SkipUnchangedFiles="true" />
        <Copy SourceFiles="@(ExcelDnaXllFile)" DestinationFiles="$(TargetDir)$(TargetName)-AddIn.xll" SkipUnchangedFiles="true" />
        <Copy SourceFiles="@(ExcelDnaXllFile)" DestinationFiles="$(TargetDir)$(TargetName)-AddIn64.xll" SkipUnchangedFiles="true" />
        <Copy SourceFiles="@(ExcelDnaExeFile)" DestinationFiles="$(TargetDir)$(TargetName)-AddIn.dna" SkipUnchangedFiles="true" />
        <Copy SourceFiles="@(ExcelDnaExeFile)" DestinationFiles="$(TargetDir)$(TargetName)-AddIn64.dna" SkipUnchangedFiles="true" />
You should be able to do something similar with the ExcelDnaPath.exe too, just post back if you need any help.
Sep 1, 2014 at 6:31 PM
Thank you for posting this.

The problem for using $(SolutionDir) from my side is that the package directory might be either under the solution directory or the project directory.
It should be possible in the Install.ps1 to detect which is the and then put the right expansion macros in the post-build steps directly.

Your .target approach looks like a novel solution too - what would be the advantage over getting the right macro expansion in place?

You might also like to vote on this Visual Studio issue, which asks for the ability to put expansion macros in the debugging command line:

Sep 2, 2014 at 8:51 AM
Hi Govert,

Thanks for your reply, with regards to your points:

To be honest I don't know enough about NuGet to comment on the reasons why you want to be able to dynamically put the packages at the solution or project level. But I guess that if NuGet intended you to do this they would provide an easy mechanism to do this. This isn't a criticism, but if all NuGet packages were implemented this way with the ${toolMacro} then none of them would build on a machine with a different directory structure to the developer's machine. So either there is an alternative approach to switching dynamically between two package directories or NuGet never intended for this approach to be taken. As I said I'm not an expert in NuGet so maybe I am being simplistic here, but I would be amazed if no one else had come up against this issue before and found a solution. Maybe it's worth posting something on the NuGet forum or on explaining what is unique about your requirements (I'm happy to do this if you can explain your exact requirements).

Regarding the msbuild targets, I was recommended this approach when I was trying to solve a similar problem. I knew it felt messy/wrong trying to modify the post build event (and then clean it up when uninstalling) so it was no surprise when I was told the 'correct/proper' way was to put these custom actions into a target. The advantage is that it keeps your build event completely separate from any events the user has written. I can see from your powershell scripts that you had to fiddle around with RegEx etc to do this. I'm guessing this could be simplified using an msbuild target.

The VS issue you mentioned makes sense, I have upvoted this for you.


Feb 16, 2015 at 3:50 PM
Hi Govert,

is there some progress with respect to this issue? Could you recommend a suitable workaround for the absolute path?

One workaround I found is to add the nuget package entry to the solution-wide nuget config (i.e. ProjectRoor/.nuget/packages.config ). This will only download the package to the solution but will not run the installation script. Then, I manually created the post-build steps to fit my deployment environment. A but more work but it works quite ok.