Visual Studio 2017 builds all project because of "missing" PDB file - visual-studio

I had a few minutes this morning to try to figure out why Visual Studio 2017 rebuild all of my projects in the solution every time I try to run the project. I think I know why this is happening but I'm not sure how to fix it.
I saw these articles:
http://michaelscodingspot.com/2017/04/28/visual-studio-keeps-rebuilding-projects-no-good-reason/
https://ofekshilon.com/2015/08/16/visual-studio-projects-that-just-keep-rebuilding-or-how-quantum-mechanics-mess-up-your-build/
Which got me to turn up build logging.
I now see that VS is looking for PDB files in the OBJ directory and since they are not there(1), VS thinks the project needs to be rebuilt.
3>Project '****.Common' is not up to date. Missing output file 'C:\*******\***\****.Common\obj\Debug\***.****.Common.pdb'.2>Build started.
1) The PDB files are not in the OBJ directory for the assembly projects. They are in the BIN directory. Note that in the main "executable" web project the PDB files are in both the OBJ and BIN directories.
So now I need to make visual studio do one of the following:
Put a copy of the PDB in the OBJ directory for all projects
Make VS check in the BIN directory for the PDB
I did some search but haven't been able to figure out a good set of search terms to find the answer to this one.
Note this is a project that has been developed using VS2012, VS2015, VS2017 and maybe some before 2012, so this might be part of the problem.

This was an issue with assembly project that had been created in older versions of Visual Studio (the projects created in VS2017 don't have the problem).
The workaround I found was to change this part of the .csproj file:
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
...
<OutputPath>bin\Debug\</OutputPath>
...
</PropertyGroup>
to:
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
...
<OutputPath>obj\Debug\</OutputPath>
...
</PropertyGroup>
Note that you can make this change in "Properties / Build" under "Output" by editing "Output path". Also note that this is apparently a workaround because I didn't need to do this to the VS2017 projects. If I go and exhaustively try to figure out the differences between the proj files, I'll update this answer.
There were a few other content items set to "Copy Always" which also forces the whole project to rebuild. I changed those to "Copy if Newer".

Related

MSBuild - how to include/exclude directories?

I am trying to build a visual studio solution from the windows command line as follows:
msbuild solution.sln /t:Build /p:Configuration=Release
But I need to exclude a certain directory from one of the projects, and include another one. How do I do that?
Use this in your project csproj file:
<Compile Include="Folder1/*" Condition=" '$(Configuration)' == 'Release' " />
<Compile Exclude="Folder2/*" Condition=" '$(Configuration)' == 'Release' " />
Of course, you already set up the Configuration property, but you can replace it with your own property and set him from command line same as Configuration.
In the project dir, add two folders "CppFilesForDebug" and "CppFilesForRelease".
The "CppFilesForDebug" folder contains "Debug1.cpp,Debug2.cpp,Debug3.cpp" while "CppFilesForRelease" folder contains "Release1.cpp,Release2.cpp,Release3.cpp ".
Then add statement in the bottom of the vcxproj file like red rectangle below:
The red rectangle means we build and compile cpp files in "CppFileForDebug" folder when using Debug mode. And in release mode, we only compile cpp files in "CppFilesForRelease" folder insteat of cpp files in "CppFilesForDebug" folder.
I test it with C++ projects in VS2015 and VS2017 and it works. I think it can go well with your command "msbuild solution.sln /t:Build /p:Configuration=Release". Please it a try and any feedback would be great.
Update:
IF your issue results from QT conflicts, In vs, go QT menu ->Qt Project Settings->MocDirectory-> change it to
.\GeneratedFiles
Note: Don forget the "." before \GenerateFiles. Hope it helps. Any update you can share here.

WindowsSDK_ExecutablePath not set correcty in VS2015 VC++ variables

I have searched a lot on the web and I couldn't find a proper solution to this, just workarounds. I wonder whether either VS2015 or WindowsSDK installation is broken.
Here is the thing:
I get issue building (in link phase) and the VS environment reports can't find the Resource Compile executable (rc.exe)
TRACKER : error TRK0005: Failed to locate: "rc.exe". The system cannot find the file specified.
I searched around on my machine and found the binary in:
C:\Program Files (x86)\Windows Kits\10\bin\10.0.16299.0\x64
So the quick workaround was to add that path to PATH and everything works fine. But I am not really happy about it as I am sure the Windows SDK installer (or VS) should handle this nicely.
If I look into VS IDE -> Project -> Properties -> Configuration Properties -> VC++ Directories and look at "Executable Directories" I am expecting to find the right path in there. So I inspect it by opening MACRO (bottom right) and filtering for WindowsSDK_ExecutablePath: there I see
$(WindowsSDK_ExecutablePath) = C:\Program Files (x86)\Windows Kits\10\bin\x86
$(WindowsSDK_ExecutablePath_arm) = C:\Program Files (x86)\Windows Kits\10\bin\10.0.16299.0\arm
$(WindowsSDK_ExecutablePath_arm64) = C:\Program Files (x86)\Windows Kits\10\bin\10.0.16299.0\arm64
$(WindowsSDK_ExecutablePath_x86) = C:\Program Files (x86)\Windows Kits\10\bin\x86
$(WindowsSDK_ExecutablePath_x64) = C:\Program Files (x86)\Windows Kits\10\bin\x64
As you can see the intel architecture folders point to a generic location (not SDK version specific) that of course doesn't have those binaries. Interestingly enough the ARM folders are correct.
I am trying to understand what has corrupted those folders...
I can guess it's the SDK installer as in the UAP.props file located in
$(WindowsSDKDir)/DesignTime/CommonConfiguration/Neutral/UAP/10.0.16299.0/
I can see this
<WindowsSDK_ExecutablePath_x86>$(WindowsSdkDir)bin\x86;</WindowsSDK_ExecutablePath_x86>
<WindowsSDK_ExecutablePath_x64>$(WindowsSdkDir)bin\x64;</WindowsSDK_ExecutablePath_x64>
although I am not 100% sure as this is post-install so it could be VS changing that.
Any ideas? Suggestions? Anyone who had the same issue and managed to find a proper fix instead of workarounds?
Right, not sure if this is the right one but digging a bit on the issue brought me at this point. What I have found is this strange block of xml code in
$(WindowsSDKDir)\DesignTime\CommonConfiguration\Neutral\UAP\10.0.16299.0\UAP.props
that looks like this:
<PropertyGroup Condition="'$(VisualStudioVersion)' != '' and '$(VisualStudioVersion)' <= '14.0'">
<WDKBinRoot>$(WindowsSdkDir)bin</WDKBinRoot>
<WindowsSDK_ExecutablePath_x86>$(WindowsSdkDir)bin\x86;</WindowsSDK_ExecutablePath_x86>
<WindowsSDK_ExecutablePath_x64>$(WindowsSdkDir)bin\x64;</WindowsSDK_ExecutablePath_x64>
</PropertyGroup>
<PropertyGroup Condition="'$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' > '14.0'">
<WDKBinRoot>$(WindowsSdkDir)bin\10.0.16299.0</WDKBinRoot>
<WindowsSDK_ExecutablePath_x86>$(WindowsSdkDir)bin\10.0.16299.0\x86;</WindowsSDK_ExecutablePath_x86>
<WindowsSDK_ExecutablePath_x64>$(WindowsSdkDir)bin\10.0.16299.0\x64;</WindowsSDK_ExecutablePath_x64>
</PropertyGroup>
Correct me if I am wrong but that doesn't seem to do anything in case you have VS2015 (which is 14.0)
So I appended this after that block:
<PropertyGroup Condition="'$(VisualStudioVersion)' == '14.0'">
<WDKBinRoot>$(WindowsSdkDir)bin\10.0.16299.0</WDKBinRoot>
<WindowsSDK_ExecutablePath_x86>$(WindowsSdkDir)bin\10.0.16299.0\x86;</WindowsSDK_ExecutablePath_x86>
<WindowsSDK_ExecutablePath_x64>$(WindowsSdkDir)bin\10.0.16299.0\x64;</WindowsSDK_ExecutablePath_x64>
</PropertyGroup>
With that change all works. I wonder why this file is populated this way. If you look at the end it includes arm and desktop.arm props. I also wonder if I can create a property file separate to this generic UAP.props.
Of course this fixes only this specific SDK version, you will have to do it for every version installed and, if you install a new one.

MSBuild 15 WebApplication.targets is missing

I am working with a web application that was written using VS2015, and is being maintained using VS2017. I am trying to write another application to build the full web stack locally using the MSBuild API and other tools. In VS2015 or VS2017 the ASP.NET Web Application project will build successfully, but when running MSBuild programmatically, I keep getting this error:
The imported project "C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v15.0\WebApplications\Microsoft.WebApplication.targets" was not found. Confirm that the path in the declaration is correct, and that the file exists on disk.
I have the following build packages installed in my app:
Microsoft.Build
Microsoft.Build.Framework
Microsoft.Build.Tasks.Core
Microsoft.Build.Utilities.Core
The standard advice I've seen in forums for this error is to install Visual Studio on the build server, but I am doing this locally and I do have Visual Studio installed. I've also read that MSBuild 15 does not come with the WebApplication.targets file. There is also a toolsVersion parameter on the constructor for Microsoft.Build.Execution.BuildRequestData that I've tried setting manually to 14.0 but it still seems like my app is trying to use MSBuild 15. (I do have MSBuild 14 installed.)
Questions:
Can I make this build run in MSBuild 14 programmatically without updating any csproj files?
Where can I get WebApplication.targets for MSBuild 15?
Solution:
Thanks in large part to #Leo-MSFT I was able to get this working. Here's how:
Uninstalled the VS2017 ASP.NET and Web Application Development workload, then reinstalled with all of its optional components. This downloaded the missing .targets file.
In my builder application, added this property to my instance of BuildRequestData to make MSBuild look in the folders used by v15, rather than using the folders used by v14.
["MSBuildExtensionsPath32"] =
"C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild"
Can I make this build run in MSBuild 14 programmatically without updating any csproj files?
MSBuildExtensionsPath32 is set internally by MSBuild. If you do not want update you .csproj file, you can try to override the value in your project file:
<PropertyGroup>
<MSBuildExtensionsPath32>C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild</MSBuildExtensionsPath32>
</PropertyGroup>
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.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)' != ''" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" />
But I'm not sure if it will introduce other error(Not tested).
Where can I get WebApplication.targets for MSBuild 15?
The path of WebApplication.targets for MSBuild 15 is:
C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Microsoft\VisualStudio\v15.0\WebApplications

ExcludeFilesFromDeployment not working in Visual Studio 2013 Publish Web

I have a fairly straightforward MVC 5 project in Visual Studio 2013. I have successfully set up publishing via Web Deploy to the server. I want to exclude a certain file from deployment without having to preview/uncheck it every time I publish (I am publishing the Release build).
I have edited the .csproj file for the project to include the <ExcludeFilesFromDeployment> tag.
<Project...>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
...
<ExcludeFilesFromDeployment>Library-that-is-not-good-for-server.dll</ExcludeFilesFromDeployment>
</PropertyGroup>
But nothing changes/the file still needs to be unchecked for addition when I go to publish in VS2013.
I have also tried adding a bin\ in front of the library, just in case. Not to mention, a warning pops up for the element that says "The element 'PropertyGroup' in namespace 'http://schemas.microsoft.com/developer/msbuild/2003' has invalid child element 'ExcludeFilesFromDeployment' in namespace 'http://schemas.microsoft.com/developer/msbuild/2003'. ..."
Microsoft's documentation that I was able to find in searches regarding excluding files from deployment, and the ExcludeFilesFromDeployment tag, http://msdn.microsoft.com/en-us/library/ee942158(v=vs.110).aspx, claim that the instructions only apply to VS2012 and partially to VS2010. Does anyone know what has changed for VS2013 or what I am doing wrong?
You need to add it in the profileName.pubxml file.
profileName.pubxml file position is:
my project ----> Properties ----> PublishProfiles ---> profileName.pubxml
Example:
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ExcludeFilesFromDeployment>
Library-that-is-not-good-for-server.dll
</ExcludeFilesFromDeployment>
''' ''''
You probably need to have the following definition also in the 'profileName'.pubxml file:
<DeleteExistingFiles>False</DeleteExistingFiles>
Please remove all files from your Temp publish location(normally obj\Release\Package\PackageTmp) after excluding some files or directories.

Correct way to use the OutDir - load and archive file test: with Teamcity and Visual Studio 2012

Background
I have an import process, which includes uploading a couple of files, which then go into an "Import" folder, the user then processes the files (get put into the database), which then get put into an "Archive" folder.
Problem
Running tests for this process, is where I'm encountering the problem.
The test import files for this are stored in a "Resources" (including Import and Archive) folder within the Tests project within the Visual Studio solution.
Current Solution: Attempt
A post-build event has been setup on the project to xcopy the "Resources" folder to the ${Outdir} - this works great in Visual Studio.
Problem
When I run Teamcity, the solution build - creates the folder (and subfolders) in /bin/Release/ rather than Teamcity's /out/ directory.
I'm sure I'm just not doing the copy in the correct way, there have been some suggestions of using MSBuild rather than xcopy, so could do with some help.
How do I setup Teamcity / my Solution to build to output these test files to the same place.
Using TeamCity
You can override the build output path by passing in the parameter to msbuild - this will override the project settings.
In the MsBuild / Visual Studio runner step, add this into the Command Line Parameters field
/p:OutputPath=out
The other alternative is to edit the project file in an editor and change the path there.
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>out\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
This will ensure that all files are output to a directory that is consistent whether you are building in Visual Studio or TeamCity
To get your test files into this directory, I would set the build action on them to Content and to copy if newer.
Hope this helps.

Resources