74

Some context:
I've followed the tutorial on using NuGet without committing packages with some success. After working around this NuGet issue by manually adding <RestorePackages> and a <Import ...> for the nuget.targets file things were working.

However, once I cloned the repository with Mercurial, I got the following error when building:

Unable to locate 'C:\...\Visual Studio 2010\Projects\MyProject\.nuget\nuget.exe'

This makes sense, because my ignore pattern prevented me from checking in the exe file. From this related SO question I inferred that it's not uncommon to have this file in version control (or is it?), but really I'd prefer not to commit NuGet.exe to version control if I can help it.


Question: Is there a convenient way to prevent needing to check in NuGet.exe?


I've tried some Google-fu, skimming the documentation, and fiddling with the NuGet.targets file, no luck so far. It seems preferable if I could just dynamically point to the NuGet.exe of the particular environment that's building the solution.

I know I could just add the exe file, but I'd prefer to know if there are other ways to handle this or know why there are no viable alternatives.

Update:
The nuget.targets file holds some relevant xml:

<!-- only (relevant) parts of the xml shown below -->
<DownloadNuGetExe Condition=" '$(DownloadNuGetExe)' == '' ">false</DownloadNuGetExe>
...
<UsingTask TaskName="DownloadNuGet" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
    <Task>
        <Code Type="Fragment" Language="cs">
        <![CDATA[
        try {
            OutputFilename = Path.GetFullPath(OutputFilename);

            Log.LogMessage("Downloading latest version of NuGet.exe...");
            WebClient webClient = new WebClient();
            webClient.DownloadFile("https://nuget.org/nuget.exe", OutputFilename);

            return true;
        }
        catch (Exception ex) {
            Log.LogErrorFromException(ex);
            return false;
        }
        ]]>
        </Code>
    </task>
</UsingTask>

I'm unfamiliar with the workings of .targets files, but this seems to be along the lines of what I'm looking for. With my cowboy-coding hat on I tried changing the false to true in the DownloadNuGetExe element, but this didn't work as expected (with or without the condition attribute).

Community
  • 1
  • 1
Jeroen
  • 60,696
  • 40
  • 206
  • 339
  • You can also delete .nuget folder and edit project file and after this you can start app. – NoWar Apr 23 '13 at 15:40

3 Answers3

123

Just checked: nuget.targets is an msbuild file. And you were on the right way, in:

<DownloadNuGetExe Condition=" '$(DownloadNuGetExe)' == '' ">false</DownloadNuGetExe>

Change the value to true:

<DownloadNuGetExe Condition=" '$(DownloadNuGetExe)' == '' ">true</DownloadNuGetExe>

But you must restart Visual Studio or reload the solution (see comments) after this to take effect.

Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92
Pavel Bakshy
  • 7,697
  • 3
  • 37
  • 22
  • 3
    Oh my lord. Can't believe the solution was to restart VS! (Why is that, anyway?) Thanks a bunch! – Jeroen Aug 19 '12 at 10:25
  • No problem. It looks like a bug that VS doesn't track changes in files which linked to csproj files and don't ask for reload. – Pavel Bakshy Aug 19 '12 at 10:31
  • 7
    You don't need to restart VS, just reload the solution to cause the projects to be re-read. – anton.burger Nov 22 '12 at 11:14
  • @shambulator thx for the tip, I've updated the answer so future visitors can easily spot that solution – Jeroen Nov 22 '12 at 13:28
  • 2
    Visual Studio uses *extremely* agressive cacheing of solution and project files (and also / especially msbuild project files loaded via import).When changing msbuild files, you can test them from command line immidiately and when finished re-load the corresponding project(s) in VS: – Sebastian P.R. Gingter Jan 10 '13 at 18:20
  • I just used this, and VS2013 did not require a restart. Maybe it's been updated to better watch the file? – ScottCate Sep 15 '14 at 14:28
  • Just restarted Visual Studio and that solved my problem... Thanks! – ChaseHardin Nov 02 '15 at 16:52
  • with VS 2015 followed the instructions: change NuGet.targets, removed .exe, restarted VS but NuGet.exe appears in working directory after rebuild! I am about to include it to the .gitignore even it is not included in common/recommended ignore files for VS. Any idea? – Ricardo stands with Ukraine Mar 16 '16 at 16:48
12

Looking at that .targets file, there's another way to do this if you neither want to check NuGet.exe in, nor download it every time. The key line is this:

<NuGetExePath Condition=" '$(NuGetExePath)' == '' ">$(NuGetToolsPath)\nuget.exe</NuGetExePath>

Following the MSBuild convention of only setting properties if they haven't already been defined, this value defaults to the solution's local copy of NuGet.exe, downloading it if the DownloadNuGetExe property is true. But MSBuild properties can be overridden by environment variables.

If you already have NuGet downloaded to some central location, you can leave DownloadNuGetExe at false and define an environment variable called NUGETEXEPATH, which will be used instead.

anton.burger
  • 5,637
  • 32
  • 48
0

Enable NuGet Package Restore enter image description here

Right click on solution then select Enable NuGet Package Restore

Liam
  • 27,717
  • 28
  • 128
  • 190
  • 1
    This does not really answer my question, right? In the first article I mention this exact instruction is included too, i.e. with my question you can assume I already *have* enabled package restore. My question is about getting `nuget.exe` when it's missing. – Jeroen Oct 13 '15 at 13:41
  • Yes.Excuse me!. I think you need to add NuGet Package for you solution – Mohammad Farahani Nov 18 '17 at 10:41