Why does Tfs2010 build my Wix project before anything else? - wix

A similar question was asked and answered about a year ago, but was either a different issue (everything was in beta) or misdiagnosed. It's located here: MSbuild task fails because "Any CPU" solution is built out of order.
My issue is that I have a wix installer project, and after upgrading to Tfs2010 on monday, the build fails on linking because it can't find the build product of the Wpf application in the project. After some digging, it's because it hasn't been built yet. Building in Vs2010 works as normal. The wix project is set to depend on the Wpf project, and when viewing Project Build Order in the IDE, everything looks as normal.
The problem was originally encountered with only two platform definitions in the solution; x86 and x64. There are also two flavors, Debug and Release, and TFSBuild.proj is set to build all four combinations. There was no occurence of AnyCPU anywhere. Per the referenced question above, I tried changing the Wpf project to use AnyCPU so that it would be built first. At this point, the wix project used the exact configuration and the Wpf project used the flavor with AnyCPU. However, doing so didn't seem to change anything.
I'm using the Tfs2010 RTM, Vs2010 RTM, and the most recent version of Wix, which at the time of this writing is 3.5.1602.0, from 2010-04-02. Anyone else running into this?
2010-04-27: After a fair amount of digging, and reproducing on a cloned VM build machine, I believe I know what's going on and also what's failing, but I don't quite know how to fix it.
The situation is that this bug seems to exhibit symptoms based on pure luck-of-the-draw project ordering in the solution file. It appears as if the solution file will just blindly build the projects in the order they appear, relying on its ability to detect unbuilt references and build them on demand when needed.
In my particular solution file, my Wix project was ordered before my Wpf application project. This resulted in the Wix project being built first, and while the dependency on the Wpf project was detected correctly, the actual MSBuild task was skipped because of the undefined $(BuildProjectReferences) variable I mention a couple of comments down from the main post in this thread. With MSBuild verbosity still on diagnostic, BuildProjectReferences can be seen as undefined building the Wix project, and it can be seen defined as true upon building the Wpf project within the task to build the Wix project. Yet, when tested, it evaluates undefined again, the task is skipped, and the Wix build fails because it can't find the build output of the unbuilt Wpf project.
So bottom line: project dependency is skipped because of bad $(BuildProjectReferences) variable. Interestingly, this variable is present only in the Wix2010.targets file, and not in wix.targets; I guess that's why this is just showing up after I installed Tfs2010 and Vs2010.
The solution: How do I make sure that BuildProjectReferences is passed along correctly to the subsequent MSBuild tasks? Is there something special with variable scoping going on?
2010-09-14: A bug was opened for this issue in the WiX toolset: http://sourceforge.net/tracker/?func=detail&atid=642714&aid=2990231&group_id=105970 and fixed a while ago. Hopefully, this is no longer an issue. If so, please do open a new bug.
To address your comment directly, nothing in my solution has an AnyCPU configuration in their build files. I created the AnyCPU configurations only to test the solution suggested by the thread I linked to in my original post. After it didn't work, I removed the AnyCPU configurations again.
Furthermore, the projects are in the same solution file, however in separate solution folders (interface folder, installer folder) if that matters.
Interestingly enough, I was going to make a small sandbox example so that I could illustrate the problem I was having, however after creating my tiny sample solution, I couldn't get the error to reproduce. This makes me think that perhaps this is a result of using a team project that was upgraded from a Tfs2008 team project rather than one that was created fresh in Tfs2010. I may try branching my project into a new one to test this theory if I can't figure out why the test solution works.
p.s. also, I'm new to stackoverflow--why on earth are comments limited in length if the "answer your own question" workflow is intended only to provide concrete answers?
So I threw the build verbosity up to diagnostic and read through it today, and one line in particular stood out to me:
Task "MSBuild" skipped, due to false condition; ('#(_ProjectReferenceWithConfiguration)'!='' and '$(BuildingInsideVisualStudio)' != 'true' and '$(BuildProjectReferences)' == 'true' and '#(_MSBuildProjectReferenceExistent)' != '') was evaluated as ('..\WpfApp\WpfApp.csproj'!='' and '' != 'true' and '' == 'true' and '..\WpfApp\WpfApp.csproj' != '').
This was seen as my installer project was attempting to build my wpf project since the wpf project is referenced. In particular, for some reason $(BuildProjectReferences) is evaluating to '' when I'm fairly sure it should be 'true'.
However earlier in the log, at the beginning of the MSBuild task for the WpfApp project, I saw this:
Task "MSBuild" (TaskId:15)
...
Initial Properties:
...
BuildProjectReferences = true
So the property was indeed correct up until the beginning of the task, but then was apparently overwritten? I'm sort of unclear as to how these properties get set.

Its a bug, a bug, a bug. I don't know, who is responsible, but here's a working dirty filthy hack:
Open your .sln file in notepad.
Find your wix projects in the list of projects.
Cut them out, and paste them back after all other projects are listed.
Cry in the shower as you try to scrub the dirty off, only to emerge hours later, rubbed raw and still with the stench of filth clinging to you like corpse's skin.

Following Rob Mensching's edit of my original post, it seems that this has indeed been fixed in WiX 3.6.0917.0 at the latest.

I was seeing this problem (wix 3.7 not finding the dependent project output) in my local and TFS builds (for both VS2010 and VS2012).
I finally got around it by setting the msbuild property /m:1 to only use a single build process. I set /m to allow msbuild to figure out how many processes it could use to simultaneously build with.

I faced with a same problem today and find a solution like this:
Open your solution file on notepad the find your setup project and change postProject setting. This will tell msbuild this project should wait another project to build. I don't know why but it is not added by default.
Project("{GUID}") = "MyInstaller", "MyInstallerPath", "{Installer Project GUID}"
ProjectSection(ProjectDependencies) = postProject
{Prebuild Project GUID} = {Prebuild Project GUID}
EndProjectSection
EndProject
'Prebuild Project GUID' is the number on the right of the project that you want to install.

TFS uses a set of properties to control the names of the solutions and configurations to build ( iterate through ). For each combination of solution and configuration it then uses the project dependencies / build order to control the order of the projects getting built. It's possible that your EXE/DLL's are AnyCPU and that your WiX is x86 and that although the WiX has a dependency on the EXE/DLL the x86 is built before your AnyCPU. Or maybe they are even in different solutions so it's kind of hard to tell without looking at your source but that's basically how it works.

What we did is to first report the bug to wix and then we found your question.
We solved the problem on our side by saying that, by default, the wix project will build the references. We updated the file C:\Program Files\MSBuild\Microsoft\WiX\v3.5\wix2010.targets by setting <BuildProjectReferences>True</BuildProjectReferences> in the project which set the path. So, yes, we have done this manually ; we have reported the bug as well as our fix.

Related

TeamCity can't find the <something>.fakes.dll

I'm setting up a CI with TeamCity 8 (v8.1.4).
I finally managed to setup TFS integration - ie checkout from TFS.
I used the super easy Auto Detect Build Steps [thank you JetBrains for that] to determine the Build Steps necessary.
I used the Get missing NuGet packages step, which works as expected.
Then I have a Visual Studio Solution build step, that seems to build great, just until the point where it wants to build the Unit Test and Integration Test projects, which both use Microsoft Fakes.
Here I can see that TeamCity tries to search everywhere for the [AssemblyNameUnderTest].Fakes.dll - where [AssemblyNameUnderTest] is whatever dll that is tested.
I haven't included that dll to my project nor in TFS, since I thought that it would be regenerated each and every time I change something to the original AssemblyNameUnderTest (ClassLibrary) Project.
Should I include the [AssemblyNameUnderTest].Fakes.dlls to the project and TFS or am I right that they are regenerated ?
And if I'm right with the regeneration, then why TeamCity can't find it ?
Thanks in advance,
Michael
Ah, so I found the answer to one of my questions: http://hamidshahid.blogspot.be/2012/11/microsoft-fakes-framework.html
The files in the "Fakes" folder are only generated at the time of
adding the fakes assembly. They are added to the solution and should
be checked into source control.
The "FakesAssemblies" folder and all the files in it are generated
whenever the project is compiled. This is important because if you are
adding fakes for assembly for a changing component, the generation of
FakesAssemblies will ensure that all changes are reflected in the
generated assembly.
So I did that - ie it is the default behaviour.
Above that my .fakes files have the "Fakes" build action, but it still isn't working for TeamCity.
Also, TeamCity uses the MSBuild.EXE from "C:\Program Files (x86)\MSBuild\12.0\Bin" for the build.
Anyone a bright idea ?
To fix the build, I removed the Fakes stuff and implemented Moq mocks.
Seems to give you more control of what exactly happens.

Referencing WiX extension in same solution as wixproj

I wrote up a quick WiX preprocessor extension to grab some product version information from a file we keep in our root folder.
I'd like to keep this extension in the same solution as our WiX setup project, because it's easier to maintain. But the problem is that when testing, we use a Debug configuration, and when releasing a build, we switch to Release. This means that I have two extensions to deal with.
How would I tell WiX to grab one depending on the current configuration?
I've been looking at the reference paths in the WiX project's properties, and added "..\MyWiXExtensions\bin\$(Configuration)\" as a folder, hoping that it would pick up the MSBuild property, but that doesn't seem to work.
I've also looked at the build events. I could copy the output dll to my setup project's folder, but wouldn't that break references if I clean my solution?
I'm using WiX 3.7 and Visual Studio 2012.
I ended up using a post-build event on my extension that would copy the output to my wixproj's folder.
I just have to build my wixproj separately from the rest of the solution to prevent file locking issues when overwriting the dll. If file locking does come up, I just have to close VS and reopen the solution.
As a side note, referencing the project itself instead of the dll could be a nice feature to have in Votive.

MSBuild sets TargetFrameworkDirectories incorrectly

When I try to build a C# Console Application (and possibly others) it appears that TargetFrameworkDirectories is set incorrectly; in particular it omits the Facades directory.
Since I've been trying to diagnose the problem for a while, here is a list of possibly relevant facts.
The problem manifested itself when trying to build in Visual Studio 2012 a project that referenced the Reactive Extension libraries (managed using NuGet). The error (or warning) was warning MSB3267: The primary reference "System.Runtime", which is a framework assembly, could not be resolved in the currently targeted framework. ".NETFramework,Version=v4.5". The problem occurs during msbuild executing ResolveAssemblyReference
I can reproduce the error from command line with msbuild, which seems simpler
Other workstations do not exhibit the problem. Running msbuild with verbosity turned up on a good machine and on the bad machine turned up some differences in the log file
On a good machine TargetFrameworkDirectories (a parameter of ResolveAssemblyReference) is C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\,C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades\ but on a bad machine it lacks the second entry (the Facades directory)
Scanning through the good and bad msbuild log files the following differences turn up:
Target AssignProjectConfiguration is skipped in the bad build, but runs in the good build
A number of targets like GetInstalledSDKLocations are skipped in the good build but are not mentioned in the bad build
The ResolveAssemblyReference task is passed Assemblies with Implicit=true in the good build but not in the bad build.
The ResolveAssemblyReference task is passed the task parameter TargetFrameworkDirectories with C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\ in the bad build, but the good build the Facades directory (see above) as a second item.
Since this is driven by C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets I diffed that file on the good and bad machine. They contained many differences. The first difference is the project element (line 17) which has an extra attribute TreatAsLocalProperty="OutDir" on the good machine. On the good machine the targets file contains more comments, such as <!-- VS10 without SP1 and without VS11 will not have VisualStudioVersion set, so do that here -->. Jumping to the AssignProjectConfiguration target, the good machine has Condition="'$(CurrentSolutionConfigurationContents)' != '' or '#(ProjectReference)'!=''" while the bad machine has Condition="'#(ProjectReference)'!=''" (which I assume explains why it was skipped).
One final thing I tried was repairing "Microsoft .NET Framework 4.5" and "Microsoft .NET Framework 4.5 Multi-Targeting Pack". It did not help.
Any advice would be appreciated, especially if I can avoid reinstalling Visual Studio 2012!
UPDATE: It seems that reinstalling .NET 4.5 followed by "merely" repairing VS2012 solved my problems. My best guess as to what caused this problem is that somehow my Microsoft.Common.targets was altered to an old version. I have no idea what could have altered the targets file.
As suggested by #leppie it was a .NET problem. For some reason repairing .NET did not seem to fix the problem. However reinstalling .NET 4.5 (followed by repairing VS2012) did seem to fix it.

Old DLL file keeps being used

I have a seemingly random problem where my project will run using an old version of a DLL file that no longer exists. Sometimes the real version of the DLL file will be used, other times an ancient version of the DLL file will be used. Who knows where Visual Studio is getting this DLL file from - it's months out of date!
I know that it is using the old DLL file, because when the application runs I start getting weird 'TypeLoadExceptions', complaining that methods don't exist or don't have implementations.
The following actions will sometimes help, sometimes not:
Restarting Visual Studio
Restarting the computer
Cleaning and rebuilding the solution
Deleting everything in \WINDOWS\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files
Searching for and deleting instances of the DLL file in \Documents and Settings\username\Local Settings\Temp
Sometimes I perform all of the above steps, and it still uses an old copy of the DLL file. Where is it hiding it?!
The same issue exists on our TeamCity server which is using MSBuild. When TeamCity tries to run unit tests it uses an old DLL file.
Now, I know that I can use assembly redirection in the web.config file, but the version number of the DLL file hasn't changed (I don't bother to update it, so it just stays at version 1). I don't want to have to start versioning the DLL files just to solve this problem. I would just like to know which particular caches I need to clear so that I can get on with developing.
It hides it in the GAC. There it may reside indefinitely. Using a more recent version may indeed solve the problem, but there is an outstanding bug in Visual Studio that has to do with choosing the correct version of DLL files. (If DLL Hell wasn't bad enough, the Visual Studio team is making it worse!)
Finding it in the GAC is tricky, and I cannot advise you on how to do that, but once the old version is deleted from there, it will not be found again. Sometimes, even though you are pointing the compiler at a newer version (by date), it will use the older version, because it has the same version level (by version). That is its bug.
Who knows where Visual Studio is getting this dll from - it's months
out of date!
The Modules Window is your friend...
It'll tell you exactly where that file is coming from. You can even use it with arbitrary processes if you attach the debugger.
I too would guess that they're hiding in the GAC.
You can look in 'C:\Windows\assembly' to see all the dlls and unregister yours from there.
The problem may exists with the build order or your projects.
If your Test project is built before the application project, this cause the behaviour you describe. To fix this: right click on your main project in VS and select the Project Dependencies... option and check the build order. Changes to the build subsequence can be made here by correctly setting these dependencies.
I had a similiar problem (but without Visual Studio). I am loading a .NET dll using UnsafeLoadFrom.
On one computer (a terminal server) the old file still remains being used, regardless of updated version numbers, etc.
The reason is simple: As long as a program instance is running, which has already loaded the old dll, the new dll will never be used. All further UnsafeLoadFrom will become the old dll although the old version doesn't exist on the harddisk anymore, because it has already loaded some time ago.
The solution is to shut down all running instances of the application or even restart the computer. Then all new instances will get the updated dll.
In my case, this was caused switching to Release mode, which had a different configuration (that used different location of the DLL).
In my case, I use Visual Studio to Publish Website, and though I check the reference of the dll file has changed, but the published dll still is old. Finally I new a Publish Web Profile and choose the right configuration (such as Debug - x86 / Release - Any CPU), publish again then the dll is corrected.
While this question is old, maybe someone will stumble upon it again in his/her quest for finding a solution.
In my case i got a CS0433 error for an ASP.Net page. After deleting the content in the obj\ and bin\ folders of the project, it worked again. Probably has to be done with a closed Visual Studio. Maybe also clean out those folders in referenced projects in the same solution (if used in the project and not pulled via Nuget).
In my case, the old DLL was in
C:\Windows\Microsoft.NET\assembly\GAC_MSIL\MyDLL\MyDLL.dll
It DID NOT show up in c:\Windows\assembly.
I did a search of my drive for MyDLL, and it showed up as indicated above. I was debugging my test app at the time, and tried to delete the offending folder...no go...it was locked by Visual Studio. I had to stop debugging my app, close Visual Studio, and then delete the folder. Problem solved!! I don't know how my DLL got there, but it hasn't showed up there since I deleted it.
It's possible that the DLL is being referenced from another folder. It could even be on a network drive if you have one in your PATH environment variable. Here's how Windows searches for DLLs:
http://msdn.microsoft.com/en-us/library/7d83bc18%28v=vs.80%29.aspx
In My Visual Studio 2015, I ensured that the offending Visual Studio project's Reference Path Listing is empty:
If you find such problem ,delete your Reference dll and pdb extensionfile add new references and rebuild your project .This often happens due to no rebuild of project,commit and updates.
The fix for me was making sure that the virtual directory in IIS was pointing to the correct directory. I have two projects on my system, a v4 and a v5. The virtual directory on my dev system was pointing to the v4 bin directory instead of my v5 bin directory - oops!
The file that was being cached in the dll, I couldn't trace the file, so I ended up renaming the file. This might not resolve the problem mentioned here but this was the fix that worked for me related to this question.
I tried a ton of things including re-installing VS 2107.
You can see where the DLL files are being loaded from in your Output window. After going through all mine looking for project DLL, I found it.
Clearing this worked for me.
C:\Users\YourUser\AppData\Local\assembly\dl3\222Q4G1T.8AT\JBEAR7PB.E3J\8bfcf9ab\6e61cbd5_30acd401\YourDLL.dll'
I actually deleted all the files in:
C:\Users\YourUser\AppData\Local\assembly\
Holy Crow! I had an old, old suite of applications including 2 web services and a bunch of class libraries and a click once application. Well, click once stopped publishing for VS 2005 with a bunch of 'not found' errors. So, rather than hack away at my registry as suggested on this site, I figured it was time to upgrade the projects to 2017. Well, when I did this, the projects references in my web service projects got lost. Then, rather than helpfully just telling me that with errors, VS 2017 must have went to some cached file in C:\Users\XXX\AppData\Local\Temp\WebSitePublish or C:\Users\XXX\AppData\Local\Microsoft\VisualStudio\8.0\ProjectAssemblies or C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\root and 'helpfully' just used those files instead! I had to do a hardcore search with a custom program to find all the files on my C:\ drive and delete them before I finally got the errors!

Where does MSBuild store it's options, and how can I change them?

We have a large project at work, under source control, including an MSBuild file to run the build. Recently, the build has stopped working on my machine (I get errors saying that 'zzz' is ambiguous in the namespace 'yyy'). The same MSBuild file is working fine on both the build server and my co-workers machines.
I have tried cloning a new copy of the project from the shared repository, but even with a clean copy, the build is failing for me. I think it must be a problem with the MSBuild settings on my machine, but I haven't been able to find anything that tells me where they are. Any help would be appreciated, since I'm starting to think my machine has just gone crazy.
So, after a lot of hair pulling, I found both the solution to my problem, and the answer to my question.
MSBuild stores it's default options in a set of .rsp files and the .targets files found in the base directory of MSBuild. In my case, this was C:\Windows\Microsoft .NET\Framework\v3.5. The trick is that the options are stored separately for the 32-bit version of MSBuild and the 64-bit version (C:\Windows\Microsoft .NET\Framework64\v3.5. Our build required modifying the default visual basic targets file, which took care of the ambiguous reference call I was getting.
My problem happened because something modified my system path to point to Framework64 instead of Framework. Since my custom .targets file was only applied to the 32-bit version of MSBuild, the ambiguous reference wasn't being resolved correctly. Unfortunately, there isn't a visual difference between running the 64-bit version of MSBuild and running the 32-bit version of MSBuild. When I corrected my system path, everything started working again.