4

I'm working in a new company, and on my first day I want to build a solution. This, however, does not work:

I have downloaded the solution locally on my PC.
I have started Visual Studio on my PC, and I'm logged in using my hotmail account.

When I press Build, I get a question about my credential Dominique.<surname>@<firm>.eu.

It is true that I am working for <firm>.eu, but I have removed my <firm>.eu Windows credentials (Start, Credential Manager, Windows credentials). As mentioned before, I am logged in Visual Studio using my hotmail account.

So my question is: why does Visual Studio ask for my Dominique.<surname>@<firm>.eu credential while restoring NuGet packages? Does anybody know why Visual Studio is asking for a credential that Visual Studio is not even supposed to be aware of?

For your information: when I go into the solution explorer, and I try to launch "Manage NuGet packages for solution", the same Dominique.<surname>@<firm>.eu credential question pops up.

More information: the file "NuGet.Config" looks as follows:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <solution>
    <add key="disableSourceControlIntegration" value="true" />
  </solution>
</configuration>

And the file NuGet.Targets looks as follows:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <PropertyGroup>
        <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">$(MSBuildProjectDirectory)\..\</SolutionDir>
        
        <!-- Enable the restore command to run before builds -->
        <RestorePackages Condition="  '$(RestorePackages)' == '' ">false</RestorePackages>

        <!-- Property that enables building a package from a project -->
        <BuildPackage Condition=" '$(BuildPackage)' == '' ">false</BuildPackage>

        <!-- Determines if package restore consent is required to restore packages -->
        <RequireRestoreConsent Condition=" '$(RequireRestoreConsent)' != 'false' ">true</RequireRestoreConsent>
        
        <!-- Download NuGet.exe if it does not already exist -->
        <DownloadNuGetExe Condition=" '$(DownloadNuGetExe)' == '' ">false</DownloadNuGetExe>
    </PropertyGroup>
    
    <ItemGroup Condition=" '$(PackageSources)' == '' ">
        <!-- Package sources used to restore packages. By default, registered sources under %APPDATA%\NuGet\NuGet.Config will be used -->
        <!-- The official NuGet package source (https://www.nuget.org/api/v2/) will be excluded if package sources are specified and it does not appear in the list -->
        <!--
            <PackageSource Include="https://www.nuget.org/api/v2/" />
            <PackageSource Include="https://my-nuget-source/nuget/" />
        -->
    </ItemGroup>

    <PropertyGroup Condition=" '$(OS)' == 'Windows_NT'">
        <!-- Windows specific commands -->
        <NuGetToolsPath>$([System.IO.Path]::Combine($(SolutionDir), ".nuget"))</NuGetToolsPath>
        <PackagesConfig>$([System.IO.Path]::Combine($(ProjectDir), "packages.config"))</PackagesConfig>
    </PropertyGroup>
    
    <PropertyGroup Condition=" '$(OS)' != 'Windows_NT'">
        <!-- We need to launch nuget.exe with the mono command if we're not on windows -->
        <NuGetToolsPath>$(SolutionDir).nuget</NuGetToolsPath>
        <PackagesConfig>packages.config</PackagesConfig>
    </PropertyGroup>
    
    <PropertyGroup>
        <!-- NuGet command -->
        <NuGetExePath Condition=" '$(NuGetExePath)' == '' ">$(NuGetToolsPath)\NuGet.exe</NuGetExePath>
        <PackageSources Condition=" $(PackageSources) == '' ">@(PackageSource)</PackageSources>
        
        <NuGetCommand Condition=" '$(OS)' == 'Windows_NT'">"$(NuGetExePath)"</NuGetCommand>
        <NuGetCommand Condition=" '$(OS)' != 'Windows_NT' ">mono --runtime=v4.0.30319 $(NuGetExePath)</NuGetCommand>

        <PackageOutputDir Condition="$(PackageOutputDir) == ''">$(TargetDir.Trim('\\'))</PackageOutputDir>
        
        <RequireConsentSwitch Condition=" $(RequireRestoreConsent) == 'true' ">-RequireConsent</RequireConsentSwitch>
        <NonInteractiveSwitch Condition=" '$(VisualStudioVersion)' != '' AND '$(OS)' == 'Windows_NT' ">-NonInteractive</NonInteractiveSwitch>
        
        <PaddedSolutionDir Condition=" '$(OS)' == 'Windows_NT'">"$(SolutionDir) "</PaddedSolutionDir>
        <PaddedSolutionDir Condition=" '$(OS)' != 'Windows_NT' ">"$(SolutionDir)"</PaddedSolutionDir>

        <!-- Commands -->
        <RestoreCommand>$(NuGetCommand) install "$(PackagesConfig)" -source "$(PackageSources)"  $(NonInteractiveSwitch) $(RequireConsentSwitch) -solutionDir $(PaddedSolutionDir)</RestoreCommand>
        <BuildCommand>$(NuGetCommand) pack "$(ProjectPath)" -Properties "Configuration=$(Configuration);Platform=$(Platform)" $(NonInteractiveSwitch) -OutputDirectory "$(PackageOutputDir)" -symbols</BuildCommand>

        <!-- We need to ensure packages are restored prior to assembly resolve -->
        <BuildDependsOn Condition="$(RestorePackages) == 'true'">
            RestorePackages;
            $(BuildDependsOn);
        </BuildDependsOn>

        <!-- Make the build depend on restore packages -->
        <BuildDependsOn Condition="$(BuildPackage) == 'true'">
            $(BuildDependsOn);
            BuildPackage;
        </BuildDependsOn>
    </PropertyGroup>

    <Target Name="CheckPrerequisites">
        <!-- Raise an error if we're unable to locate nuget.exe  -->
        <Error Condition="'$(DownloadNuGetExe)' != 'true' AND !Exists('$(NuGetExePath)')" Text="Unable to locate '$(NuGetExePath)'" />
        <!--
        Take advantage of MsBuild's build dependency tracking to make sure that we only ever download nuget.exe once.
        This effectively acts as a lock that makes sure that the download operation will only happen once and all
        parallel builds will have to wait for it to complete.
        -->
        <MsBuild Targets="_DownloadNuGet" Projects="$(MSBuildThisFileFullPath)" Properties="Configuration=NOT_IMPORTANT;DownloadNuGetExe=$(DownloadNuGetExe)" />
    </Target>

    <Target Name="_DownloadNuGet">
        <DownloadNuGet OutputFilename="$(NuGetExePath)" Condition=" '$(DownloadNuGetExe)' == 'true' AND !Exists('$(NuGetExePath)')" />
    </Target>

    <Target Name="RestorePackages" DependsOnTargets="CheckPrerequisites">
        <Exec Command="$(RestoreCommand)"
              Condition="'$(OS)' != 'Windows_NT' And Exists('$(PackagesConfig)')" />
              
        <Exec Command="$(RestoreCommand)"
              LogStandardErrorAsError="true"
              Condition="'$(OS)' == 'Windows_NT' And Exists('$(PackagesConfig)')" />
    </Target>

    <Target Name="BuildPackage" DependsOnTargets="CheckPrerequisites">
        <Exec Command="$(BuildCommand)" 
              Condition=" '$(OS)' != 'Windows_NT' " />
              
        <Exec Command="$(BuildCommand)"
              LogStandardErrorAsError="true"
              Condition=" '$(OS)' == 'Windows_NT' " />
    </Target>
    
    <UsingTask TaskName="DownloadNuGet" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
        <ParameterGroup>
            <OutputFilename ParameterType="System.String" Required="true" />
        </ParameterGroup>
        <Task>
            <Reference Include="System.Core" />
            <Using Namespace="System" />
            <Using Namespace="System.IO" />
            <Using Namespace="System.Net" />
            <Using Namespace="Microsoft.Build.Framework" />
            <Using Namespace="Microsoft.Build.Utilities" />
            <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://www.nuget.org/nuget.exe", OutputFilename);

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

Edit after some more investigation

Apparently the whole thing is caused because my company is working with Azure Devops technology. While having a look at the corresponding help pages, I get the following message

"We have so many authentication types and authentication methods."

When I surf to the reference my company is using, either using my company e-mail or my personal e-mail, I don't get access (error message TF400813).

I just want to say: I'm not a bad person: just give me access!!

How does this work? (As simple as possible, please)

Another edit

As mentioned on the Microsoft website, I've added the following lines to my NuGet.Config file:

<packageRestore>
  <!-- The 'enabled' key is True when the "Allow NuGet to download missing packages" checkbox is set.
       Clearing the box sets this to False, disabling command-line, automatic, and MSBuild-integrated restore. -->
  <add key="enabled" value="True" />
</packageRestore>

Yet more information

As mentioned on the Microsoft website, I can try to do the restore manually, but this fails as nothing should be done:

cd <solution_directory or project directory, the results are equal>
Prompt>msbuild -t:restore

Nothing to do. None of the projects specified contain packages to restore.

How is it possible Visual Studio doesn't know that he needs to restore some NuGet packages?

Peter Csala
  • 17,736
  • 16
  • 35
  • 75
Dominique
  • 16,450
  • 15
  • 56
  • 112
  • "Company uses Azure Devops" what is shown when you go to Team Explorer -> green connection icon left of 'search work items' --> manage connections --> connect to a project? What account is shown? – Olaf Jun 02 '21 at 10:46
  • As for the packages, have you tried to use nuget restore in the Package Manager Console? For me this forces a restore on every package. – Olaf Jun 02 '21 at 10:48
  • @Devilscomrade: how does this work? I've typed `Get-Package ".Framework"`, and it mentions that the path is not of a legal form. Do you know how to say `Restore all NuGet packages` in the Package Manager Console? – Dominique Jun 02 '21 at 11:40
  • @Dominique yes, use `nuget restore` in the directory of your solution (or project) folder. If there are multiple .sln or .csproj files in the dir you can use the following command: `nuget restore <.sln or .csproj name without extension>` You can find the Package Manager Console in Visual Studio, easiest way is to use the search box at the top. If you have an older version of Visual Studio you can find it in Views -> Other Windows. – Olaf Jun 02 '21 at 12:10
  • @Devilscomrade: pardon my ignorance, but where can I type `nuget restore`? I tried in the default command prompt, I tried in Visual Studio's developer command prompt and I tried in the Nuget Package Manager, but nowhere the command `NuGet` is understood (I'm working on a Windows system, so everything is case insensitive). – Dominique Jun 02 '21 at 12:16
  • 2
    @Dominique Check the prerequisites for the NuGet command to be recognized https://learn.microsoft.com/en-us/nuget/consume-packages/install-use-packages-nuget-cli#prerequisites StackOverflow https://stackoverflow.com/questions/45610728/nuget-is-not-a-recognized-as-an-internal-or-external-command – Akshay G Jun 02 '21 at 12:40
  • 1
    @Devilscomrade: you have indeed found the solution: make sure I have a Nuget.exe I can use (download it from https://dist.nuget.org/win-x86-commandline/latest/nuget.exe (as mentioned in https://learn.microsoft.com/en-us/nuget/consume-packages/install-use-packages-nuget-cli#prerequisites, add the Nuget's location to the `PATH` environment variable, go to the solution's directory and in there, launch `NuGet restore` (even without solution reference), and everything works. Please put this into an answer, so I can accord you the bounty. – Dominique Jun 02 '21 at 13:35
  • 1
    I helped you to add Nuget's location to the PATH environment variable :P ... an upvote in the comment section would make me happy :D – Akshay G Jun 02 '21 at 13:56
  • @AkshayGaonkar: nothing would please me more than splitting the bounty between you and Satan's friend :-) (https://stackoverflow.com/users/6803592/devilscomrade). – Dominique Jun 02 '21 at 14:00
  • @Dominique I would be down for that, if that's even possible. I've summed up everything from the comments into a concise answer. I will remove the nuget.exe PATH part if Akshay Gaonkar adds an answer. – Olaf Jun 02 '21 at 14:21

2 Answers2

2

To force a full restore of the nuget packages of your project do the following:

Use nuget restore in the directory of your solution (or project) folder.

If there are multiple .sln or .csproj files in the dir you can use the following command: nuget restore <.sln-or-.csproj-name-without-extension>. This can be done in any command window.

Thanks to @Akshay Gaonkar:

For this to work, nuget.exe needs to be included in your PATH environment variables. See https://learn.microsoft.com/en-us/nuget/consume-packages/install-use-packages-nuget-cli#prerequisites and nuget is not a recognized as an internal or external command on how to do this.

This answer is a sum-up of the comments which led to the problem being resolved

Olaf
  • 1,038
  • 8
  • 20
  • Thanks for the mention. A single answer will be helpful for future references. – Akshay G Jun 02 '21 at 14:35
  • delete the packages folder and try again. – Akshay G Jun 02 '21 at 14:38
  • I did delete the packages folder: the packages folder is part of the project (solution) and I had completely removed that. – Dominique Jun 02 '21 at 14:38
  • 1
    The Global NuGet.config might have got updated. Check the config in this path %appdata%\NuGet\ Some system does not have the NuGet online package source configured correctly https://api.nuget.org/v3/index.json – Akshay G Jun 02 '21 at 14:52
-1

The credential seems to be from the nuget package. You can check the sources in packages.config.

Dylan
  • 504
  • 2
  • 5
  • 9