4

I added Fody ProperyChanged to two projects in my solution. Package Restore is enabled on the solution. However, the TFS Build Service fails building with the following error:

WindowsUI.csproj (443): The imported project "SolutionDir\Tools\Fody\Fody.targets" was not found. Confirm that the path in the declaration is correct, and that the file exists on disk.

The folder is indeed not there. I could check it into source control, obviously. However, should it not be populated by the NuGet Package Restore? Or am I misunderstanding what NuGet Package Restore does?

buckley
  • 13,690
  • 3
  • 53
  • 61
Matthias Meid
  • 12,455
  • 7
  • 45
  • 79

4 Answers4

3

I ran into a similar problem trying to get a solution to build on Visual Studio Online. Problem is that packages are restored before a project build, but before that the project files and target inclusions from packages (still to be restored) have already been interpreted.

Use the before build hook as described here:

http://sedodream.com/2010/10/22/MSBuildExtendingTheSolutionBuild.aspx

In your before.solutionname.sln.targets file put something like this to force all packages to be restored before even the first project is built:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0"
     DefaultTargets="Build"
     xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

<Target Name="BeforeBuild" BeforeTargets="Build">
 <Message Text="Restoring all nuget packages before build" Importance="high">
 </Message>
<Exec Command=".\.nuget\NuGet.exe restore YourSolution.sln" />
</Target>
</Project>

If you have external package sources configure them in your nuget.config file which should also be in the .nuget folder. For example:

<configuration>
  <solution>
    <add key="disableSourceControlIntegration" value="true" />
  </solution>
  <packageSources>
    <add key="NuGet official package source" value="https://nuget.org/api/v2/" />
    <add key="YourSource" value="http://yoursource.somewhere.net/nuget" />
  </packageSources>
  <packageRestore>
    <!-- Allow NuGet to download missing packages -->
    <add key="enabled" value="True" />

    <!-- Automatically check for missing packages during build in Visual Studio -->
    <add key="automatic" value="True" />
  </packageRestore>
</configuration>
Major Noob
  • 46
  • 4
2

UPDATE: This answer now only applies to versions prior to 1.13.0.0.

The files in SolutionDir\Tools\Fody cannot be deployed through nuget and needs to be checked into source control

Simon
  • 33,714
  • 21
  • 133
  • 202
  • OK, thanks for the official answer, Simon :) - since the project is part of multiple solutions and each of them needs the files under `Tools`, I'll try Sayed's solution anyway before marking this as an answer. – Matthias Meid Jan 15 '13 at 08:57
  • @Mudu see my comment on Sayeds answer – Simon Jan 15 '13 at 10:12
2

As of version 1.13.0.0 (released March 23, 2013) Fody is a 100% nuget deployed tool and as such it will work with package restore.

https://nuget.org/packages/Fody/

This will appear when you install the Fody Nuget https://github.com/Fody/Fody/blob/master/NuGet/readme.txt

Simon
  • 33,714
  • 21
  • 133
  • 202
1

You are running into the same issue that I did when I tried to ship a build update in NuGet package. The issue is that NuGet package restore is invoked during the build process. Because of this if NuGet package restore restores a .targets file that is imported, it is restored too late. By the time the file is written to disk the <Import element has already been evaluated and skipped due to the file not being on disk.

The best thing that I have found is to build another project to invoke the package restore for you. In order to smooth this out for my own SlowCheetah NuGet package when the NuGet package is installed I create a packageRestore.proj file in the same director as the .csproj/.vbproj. Then users can build this project file and then the .sln/.csproj/.vbproj. By doing this the NuGet packages are restored and then the build process is kicked off.

If you are interested in using my packageRestore.proj I can re-factor that part of SlowCheetah NuGet package into its own and your NuGet package can depend on that one. Let me know if you are interested in that.

Sayed Ibrahim Hashimi
  • 43,864
  • 17
  • 144
  • 178
  • Thank you (wasn't me who downvoted), I'll try out whether it suits our needs better than checking it in as Simon suggests. What I did try before asking (think it points to a similar direction) was checking in `Fody.targets` only and re-ordering the build steps - but no success. – Matthias Meid Jan 15 '13 at 09:02
  • Thanks, its frustrating when ppl downvote with no comment :( Glad to know it wasn't u. – Sayed Ibrahim Hashimi Jan 15 '13 at 09:24
  • @SayedIbrahimHashimi i voted you down. an yes i really should have added a comment. Sorry my bad. I voted it down because your solution simply wont work. The files in question do not exist as part of a nuget package and, as such, any attempt to restore them will not work. – Simon Jan 15 '13 at 10:11
  • Based on the question I assumed that Fody.targets was in a NuGet package and the OP enabled package restore with the hopes that the files would be placed on the server in time to be imported. If that's not the case then you're correct my approach may not work. I'm not familiar with the package being used. – Sayed Ibrahim Hashimi Jan 15 '13 at 17:12
  • @SayedIbrahimHashimi I added a pre-build event to my project with `"$(SolutionDir).nuget\nuget" install "$(ProjectDir)packages.config" -OutputDirectory "$(SolutionDir)Packages"` to restore packages *before* build. Am I correct this also an approach to address the issue you described, though less smoothly of course? – Matthias Meid Apr 08 '13 at 16:24
  • If the "pre-build" event is in the project itself which relies on a NuGet package to restore a file that is imported during build then you will run into the same issue. NuGet pkg restore itself is implemented as target which is executed "pre-build". The issue is that it's a part of the build, its not technically before build but during it. – Sayed Ibrahim Hashimi Apr 12 '13 at 00:57