Ted Nyberg
Ted Nyberg

Reputation: 7391

Why does MSBuild only work properly in the developer command prompt?

I'm building a project locally using msbuild.exe like:

C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe MyProject.csproj

When I execute it through the Developer Command Prompt, everything works as expected.

However, when I execute it through the standard Command Prompt, I get an error saying:

The imported project "C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v12.0\WebApplications\Microsoft.WebApplication.targets" was not found.

If I look up that folder path, I can indeed verify it's invalid (I only have VS 2015 installed on the machine).

So why isn't it working in Command Prompt, or conversely: why is it working in Developer Command Prompt?

Edit: The .csproj file is pretty much the Visual Studio 2015 default for an ASP.NET 4 website, and it specifies:

<PropertyGroup>
  <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
  <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />

To me it seems it would default to 10.0 if VisualStudioVersion isn't set, but judging from the error message it's assuming VS version 12.0.

I realize I could just modify the .csproj file, replacing 12 with 14, but I'd rather not go for a workaround, but instead understand why it's working in the Developer Command Prompt, but not the standard one.

I'm guessing it potentially has to do with different environment variables, or something along those lines?

Upvotes: 2

Views: 3802

Answers (2)

Ted Nyberg
Ted Nyberg

Reputation: 7391

Hans Passant pointed me in the right direction in the comments, and typing where msbuild.exe in the Developer Command Prompt showed that it had two paths to MSBuild:

C:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild.exe C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe

The first one works in both the standard Command Prompt, and the Developer Command Prompt.

The second one (which my build script had retrieved from the registry) only works in Developer Command Prompt, probably explained by what Pawel said in his answer (essentially due to missing/different environment variables).

In my build script, I changed the registry path from...

HKLM\SOFTWARE\Microsoft\MSBuild\ToolsVersions\4.0\

to...

HKLM\SOFTWARE\Microsoft\MSBuild\ToolsVersions\14.0\

...and that produces the proper (current) MSBuild path in the build script.

Upvotes: 0

Paweł Łukasik
Paweł Łukasik

Reputation: 4153

When you run Developer Command Prompt you basically run VsDevCmd.bat from VisualStudio's Tools folder and sets some environment variables for the Console that you will be working with. Without those msbuild can't find correct file.

For example it sets VisualStudioVersion environment variable

@rem VisualStudioVersion
@rem -------------------
@set VisualStudioVersion=14.0

It depends on the .csproj but I suspect you might have something similar in it

<PropertyGroup>
    <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">12.0</VisualStudioVersion>
    <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" /> 

So if the $(VisualStudioVersion) is not defined (and it won't in standard Command Prompt) it will use the version 12. And when you run it through Developer Command Prompt this gets set to 14 and you're good to go.

Upvotes: 8

Related Questions