Search code examples
visual-studiomsbuildvisual-studio-2017visual-studio-extensions

Visual Studio 2017 extension - VSToolsPath not working


I'm updating an old Visual Studio extension for VS 2017. It compiles fine from Visual Studio and msbuild in debug and release on my local computer.

This is the msbuild command line I am using:

msbuild VxCop.sln /p:ToolsHome=C:\ProgramData\chocolatey\bin /p:Configuration=Release /p:Platform="Any CPU"  

However, on the build machine (TFS Build 2010) calling msbuild.exe with the same command line it fails with this error

In order to fix this I am trying to specify VSToolsPath. I've tried various things such as altering the VSToolsPath entry in the .csproj (which seems to not be taken into account since doing this had no effect) and also passing it on the command line:

msbuild VxCop.sln /p:ToolsHome=C:\ProgramData\chocolatey\bin /p:Configuration=Release /p:Platform="Any CPU"  /p:VSToolsPath=Packages\Microsoft.VSSDK.BuildTools.15.1.192\tools\

This causes a very strange error:

CopyFilesToOutputDirectory:                                                                                          
  Copying file from "obj\Release\SymCop.dll" to "bin\Release\SymCop.dll".                                            
  SymCop -> H:\src\tools\VisualStudioExtensions\Main\VxCop\source\SymCop\bin\Release\SymCop.dll                      
  Copying file from "obj\Release\SymCop.pdb" to "bin\Release\SymCop.pdb".                                            
Done Building Project "H:\src\tools\VisualStudioExtensions\Main\VxCop\source\SymCop\SymCop.csproj" (default targets).

Done Building Project "H:\src\tools\VisualStudioExtensions\Main\VxCop\VxCop.sln" (Build target(s)) -- FAILED.        

Done Building Project "H:\src\tools\VisualStudioExtensions\Main\VxCop\build.proj" (default targets) -- FAILED.       


Build FAILED.                                                         
    0 Warning(s)                                                      
    0 Error(s)                                                        

The actual extension project isn't appearing in the log at all, and there's no, y'know, errors. But the build returns as failed, the return code is non-zero, and the vsix project seems to not be built (its output is missing)

Hopefully someone has some suggestions

Thanks

Edit:

For those reading this in the future, the problem seemed to be that there was an <Import> further down in the same file which didn't care about my update to $(VSToolsPath).

Changing that import fixed it:

 <Import Project="$(SolutionDir)\packages\Microsoft.VSSDK.BuildTools.15.1.192\tools\VSSDK\Microsoft.VsSDK.targets" 
 />

Solution

  • Visual Studio 2017 extension - VSToolsPath not working

    I got the same result as you based on your scripts. After installed the NuGet package Microsoft.VSSDK.BuildTools to the project, the Microsoft.VSSDK.BuildTools.props will be imported in to project file, open the project file, you can find below Import:

    <Import Project="..\packages\Microsoft.VSSDK.BuildTools.15.1.192\build\Microsoft.VSSDK.BuildTools.props" Condition="Exists('..\packages\Microsoft.VSSDK.BuildTools.15.1.192\build\Microsoft.VSSDK.BuildTools.props')" />
    

    Then open this props file, you can notice below scripts snippet:

    <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
      <PropertyGroup Label="VSSDK_NuGet_Configuration">
        <ThisPackageDirectory>$(MSBuildThisFileDirectory)..\</ThisPackageDirectory>
        <VSToolsPath>$(ThisPackageDirectory)\tools</VSToolsPath>
        <VsSDKInstall>$(VSToolsPath)\VSSDK</VsSDKInstall>
        <VsSDKIncludes>$(VsSDKInstall)\inc</VsSDKIncludes>
        <VsSDKToolsPath>$(VsSDKInstall)\bin</VsSDKToolsPath>
      </PropertyGroup>
    </Project>
    

    In this case, NuGet package override the value VSToolsPath with $(ThisPackageDirectory)\tools. So MSBuild will skip set the value setting in the next step in the project file:

      <PropertyGroup>
        <MinimumVisualStudioVersion>15.0</MinimumVisualStudioVersion>
        <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
        <NuGetPackageImportStamp>
        </NuGetPackageImportStamp>
      </PropertyGroup>
    

    Because NuGet have already set the value $(VSToolsPath), the value of Condition="'$(VSToolsPath)' == ''" would be False. In addition, you can add a target to check if the value is set, like:

      <Target Name="CheckVSToolsPath" BeforeTargets="Build">
        <Message Text="$(VSToolsPath)"></Message>
      </Target>
    

    You will find this value is set to:

    C:\Users\Admin\Documents\Visual Studio 2017\Projects\VSIXProject2\packages\Microsoft.VSSDK.BuildTools.15.1.192\build\..\\tools
    

    Summary above, the value of VSToolsPath was imported correctly, we do not need to passing it on the command line.

    After in-depth investigation, I found the reason for the previous error "MSB4226: The imported project "(...)\VSSDK\Microsoft.VsSDK.targets" was not found." is that the MSBuild property of "VisualStudioVersion" not be set on the build server.

    See below link for detail info Building a VSIX extension with the Visual Studio 2017 Build Tools:

    something that a machine with the full Visual Studio 2017 does and that a machine with the Build Tools 2017 does if you open a developer command prompt. Since I was not using it, I passed it as a parameter to the MSBuild script. It can be defined too inside the .csproj file, something that previous Visual Studio versions did automatically but recent versions don’t.

    So to resolve the error "MSBuild4226", you should pass the visual studio version on command line:

    msbuild VxCop.sln /p:ToolsHome=C:\ProgramData\chocolatey\bin /p:Configuration=Release /p:Platform="Any CPU" /p:VisualStudioVersion=15.0
    

    After using this command line, the error MSBuild 4226 was resolved.

    Hope this helps.