6

I am using Visual Studio 2013 with an asp.net project. One of the projects gives the error below. Why is it looking for LC.exe in the wrong path? My Windows 8.1 SDK is installed and I have an lc.exe at

C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools

and a 64bit version and I have a registry key at

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v8.1A

I am looking at Microsoft.Common.targets under C:\Windows\Microsoft.NET\Framework\v4.0.30319 and this key exists: SdkToolsPath="$(TargetFrameworkSDKToolsDirectory)". Then looked at Microsoft.NetFramework.CurrentVersion.props under

C:\Program Files (x86)\MSBuild\12.0\Bin

and TargetFrameworkSDKToolsDirectory is defined at $SDK40ToolsPath. According to MSBuild /v:diag,

SDK40ToolsPath = C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools 

which looks good. The project's target in VS in .NET 4.0.

So why is it still looking at the wrong folder or registry key? The interesting thing is when I rebuild the project after getting the error message, the project builds fine.

Error   5   
Task could not find "LC.exe" using the SdkToolsPath 
    "C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\bin\NETFX 4.0 Tools\" 
or the registry key 
    "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v8.0A\WinSDK-NetFx40Tools-x86".
Make sure the SdkToolsPath is set and the tool exists in the correct processor 
specific location under the SdkToolsPath and that the Microsoft Windows SDK is 
installed   
    C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets  2428    5   SuperReports
three_pineapples
  • 11,579
  • 5
  • 38
  • 75
Tony_Henrich
  • 42,411
  • 75
  • 239
  • 374
  • 4
    It looks for the right SDK, just not the right subdirectory. It is stored in v7.0A\bin. How it ended up gluing "NETFX 4.0 Tools" at the end is hard to guess. This might just be an MSBuild bug, the license compiler doesn't exactly get much use and the upheaval due to SDK 8.x left a lot of scars. Simplest hack is to just create the subdirectory yourself and copy lc.exe into it. Do review the need for lc.exe, very odd to use it in a web project. – Hans Passant Oct 19 '14 at 11:19
  • That worked. You can make it an answer. – Tony_Henrich Nov 03 '14 at 07:33
  • I still think it is odd that it claims in the error message that it is looking in v7.0A . – JDługosz Nov 03 '14 at 14:17

3 Answers3

4

It turns out you can specify the path to the SDK directly in the .csproj file:

<TargetFrameworkSDKToolsDirectory>C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6 Tools</TargetFrameworkSDKToolsDirectory>

and the build found lc.exe that way.

I previously expected to set this using <SdkToolsPath>, but that didn't work. In Microsoft.Common.targets, SdkToolsPath gets set from TargetFrameworkSDKToolsDirectory, so I tried that and it worked. This is on Visual Studio 2015, and msbuild being called from ant.

Solution found via MSBuild Using Incorrect Version of sgen.exe to Generate XmlSerializer dlls?

Community
  • 1
  • 1
TomEberhard
  • 907
  • 10
  • 11
1

Do you have a PlatformToolset property defined in your project before the imports? I think it uses that and maybe the ToolsVersion attribute on the Project XML element to choose between multiple installed SDKs. I think, from similar path funny business, that the IDE sets paths to find things based on the PlatformToolset which it looks for in a specific place in the project (while building from MSBuild command line it works no matter how it was set).

Here is an example from a vcxproj file:

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

⋮

<PropertyGroup Label="Globals">
  <ProjectGuid>{⋯⋯⋯}</ProjectGuid>
  <RootNamespace>blahblahblah</RootNamespace>
  <ConfigurationType>StaticLibrary</ConfigurationType>
  <PlatformToolset>Windows7.1SDK</PlatformToolset>
  <!-- NB: PlatformToolset must be repeated in each top-level project file -->
  <Keyword>Win32Proj</Keyword>
</PropertyGroup>

I think there are two reasons why this gives funny results if placed in a common property page: First, it needs to be set before the standard built-in logic is imported (e.g. Microsoft.Cpp.Default.props), and second the IDE somehow sets paths itself or does something with the generated solution file, and it looks for that property in the main file. I learned this when I was getting wrong paths (wrong version of an EXE was being used) when built by pressing F7 when it worked fine invoking MSBuild from a command line.

In the IDE, check the Platform Toolset in the properties editor for the project. Make sure it is shown in boldface; that is, set directly there rather than inherited even if it has the correct version showing.

Prop Page dialog from VS10

JDługosz
  • 5,592
  • 3
  • 24
  • 45
1

I went with a slightly different hack than the one suggested by Hans Passant above. My scenario is my builds are executed via Jenkins (a CI tool), using MSBuild 2015, in a Windows 2008 server.

Microsoft SDK 10 does not support Windows 2008, according to the docs. I tried playing with both SdkToolsPath and FrameworkOverride msbuild command line parameters but without success (did not try them together, have just realized while typing).

In any case, something that worked, was that yes - I was not able to force msbuild to use the newer SDK version instead of the one from Windows 7 (it insists in taking LC.exe from C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\NETFX 4.0 Tools) - so my hack was to overwrite the LC.exe with the one from SDK 10 (I have installed in my local machine, not in the build server, running Windows 2008).

My build finally succeeded.

Veverke
  • 9,208
  • 4
  • 51
  • 95
  • After trying every other alternative on the internet, this was the only one that worked for me. I couldn't find a way to force the msbuild on my Windows Server 2008 to use v10.0A\bin\NETFX 4.6.2 Tools\lc.exe. It just kept refering to v8.1A NETFX 4.5.1. Would like know a way to solve it simply by parameterizing the msbuild, though... – Gabriel Rainha May 31 '17 at 18:55