Project references outside solution in VS2010 - visual-studio

According to this it should be possible to reference projects outside solution and have it working in VS and command line but not TFS.
Unfortunately, when I've tried to partition my solution this way, it didn't work neither in VS2010/devenv nor in msbuild.
In both cases the error was:
The OutputPath property is not set for project 'Common.csproj'.
Please check to make sure that you have specified a valid combination
of Configuration and Platform for this project. Configuration='Debug'
Platform='AnyCPU'. This error may also appear if some other project
is trying to follow a project-to-project reference to this project,
this project has been unloaded or is not included in the solution, and
the referencing project does not build using the same or an equivalent
Configuration or Platform.
However, current Platform is "x86" and no matter which platform and configuration I set in VS or msbuild it's always trying Debug|AnyCPU. In case of msbuild if I set /p:OutputPath=bin\x86\Debug it propagates to child projects correctly.
Is this a bug, can I work-around it ?
UPDATE
Found the bug in MS Connect. Unfortunately closed as Won't Fix :(
UPDATE 2
Found workaround: set ShouldUnsetParentConfigurationAndPlatform=false. Both on command line for msbuild and in project file (before any imports) to fix Visual Studio.

If I understand the problem correctly, it's actually because the AssignProjectConfiguration target is not correctly setting the configuration / platform properties for those projects.
If you know what their configurations and platforms should be, you could always just inject a target to run right after the AssignProjectConfiguration target, and override the SetConfiguration and SetPlatform properties on each item representing an unresolved (meaning not part of the solution configuration) inter-project reference.
For some stupid reason, the Microsoft-provided target stores the list of unresolved project references in the same collection as the resolved ones (but nowhere else), which leaves you with 2 options:
Just set each project's properties manually (ie. hard-coding via a dynamic ItemGroup element inside your injected target).
Call the AssignProjectConfiguration task yourself from your injected target, collect the unassigned outputs to assign them all a default configuration / platform of your choosing.
Either way, once you have your list of correctly configured project references, you can simply replace the unresolved items in the ProjectReferenceWithConfiguration item group with their manually modified counterparts (using another dynamic ItemGroup element with a Remove and then an Include).
Mind you, I wouldn't do things the way you are doing them. If you want to split your product into several solutions, then I would just have each solution publish shared outputs into a common staging area and have .proj scripts to link them together. I've learnt the hard way that command-line-style MSBuild and inside-VS-style MSBuild do not mix (they have made some odd compromises to ensure interoperability with non-MSBuild project systems, of which the whole AssignProjectConfiguration-with-VS-provided-solution-config-XML process is one).

I encountered something similar in VS2012. For me, it was related to the ShouldUnsetParentConfigurationAndPlatform property of the AssignProjectConfiguration target being set to true during the build. This resulted in "GlobalPropertiesToRemove = Configuration;Platform" which caused the Configuration and Platform properties to be cleared for the project reference.
I was able to see this occurring by looking in the Build output window after setting Tools -> Options -> Projects and Solutions -> Build and Run -> MSBuild project build output verbosity -> Diagnostic.
With a blank Configuration/Platform, this caused the following line in some of my projects to match, resulting in Debug assemblies in the project output even in a Release build:
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
The solution was to modify those csproj files to specify Release as the configuration to use when the Configuration variable was empty/blank:
<Configuration Condition=" '$(Configuration)' == '' ">Release</Configuration>

Related

Microsoft (TFS) Build server - The type or namespace name '...' does not exist in the namespace '...' (are you missing an assembly reference?)

I am working on setting up a buildserver for our team.
Background
We are using Microsoft Visual Studio 2010 Ultimate. Our product contains C# code(mainly), external DLL’s and C code. We are working with .Net 4.0 and have more than 70 projects.
We are working with 3 branches of our code:
Production branche(what is currently released)
Test branche(hot fixes, bug fixes, end user testing)
Development branche(adding new fetures)
All the branches are under TF source control.
Goal
What we want is to have a build server to build and run all the unit tests for all the branches once a day, the build server should use the code in the source control. Our goal is to have some fast standard error detection. We would prefer as little to no maintaining of the build server.
We are not going to use the builds the buildserver produce, all we want is to use the build server to continuously to build and unit test our branches.
What is set up
There are currently set up two the build definition, one for the Test Branche and one for the Development Branche, both build definitions taking the code from the source control(that part works all good), but here is where the fun begins.
Problem
The Test Branche can build and run unit tests all fine.
The Development Branche cannot build due to an(or like 5 of) errors:
The type or namespace name 'XXX' does not exist in the namespace 'YYY' (are you missing an assembly reference?)
The error is for project X refereing to project Y. Both project X and Y is C# .Net 4.0 projects and we have fully control over both of them, both X and Y is compiled to DLL’s. Project Y contains a Interface the classes in project X are implementing.
The annoying detail is there is no difference in the Test Branche and Development Brance for either project X or Y. The two projects have been fully identical the last 3 month.
So the question is, why does it work in the Test Branche but not in the Development branche?
I have tested:
- The projects are correctly refered to each other.
- All 3 Branches have no problem building on my own / any of my co-workers development machines(we have tested on 5 different machines).
- I have tried to delete the whole X project and recreate it, didn’t work.
- I have tried to delete the whole Y project and recreate it, didn’t work.
- I have tried to change the namespace for project X project and its classes, didn’t work.
- I have tried to change the namespace for project Y project and its classes, didn’t work.
- (I have even restarted my development machine)
- All the changes have always been checked into the source control where after the buildserver was set to build.
Extra information
I have been digging around in the logging files and found some interessting details, this is for the details of building project X in the Development Branche
Task "AssignProjectConfiguration"
Project reference "..\..\A" has been assigned the "Debug|x86" configuration.
Project reference "..\..\Y" has been assigned the "Debug|x86" configuration. (can see there is a project Y)
Project reference "..\..\B" has been assigned the "Debug|x86" configuration.
But then in the Task ”ResolveAssemblyReference”
Task "ResolveAssemblyReference"
TargetFrameworkMoniker:
.NETFramework,Version=v4.0
TargetFrameworkMonikerDisplayName:
.NET Framework 4
TargetedRuntimeVersion:
v4.0.30319
Assemblies:
System
System.Xml.Linq
System.Data.DataSetExtensions
Microsoft.CSharp
System.Data
System.Xml
System.Core
AssemblyFiles:
C:\Builds\1\A
C:\Builds\1\B
(----- Missing project Y -----)
C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\mscorlib.dll
Where in the Test Brance for the same task
Task "ResolveAssemblyReference"
TargetFrameworkMoniker:
.NETFramework,Version=v4.0
TargetFrameworkMonikerDisplayName:
.NET Framework 4
TargetedRuntimeVersion:
v4.0.30319
Assemblies:
System
System.Data.Entity
System.Xml.Linq
System.Data.DataSetExtensions
Microsoft.CSharp
System.Data
System.Xml
System.Core
AssemblyFiles:
C:\Builds\1\A
C:\Builds\1\B
C:\Builds\1\Y (There it is)
C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\mscorlib.dll
So it feels like it for some reason just ”forgets” the reference from project X to project Y.
Help
I had the same problem.
It took me few hours to find out that in this case the problem was not my fault :-)
http://support.microsoft.com/kb/2516078 :
This issue occurs due to a bug in the Path.GetFullPath in .NET Framework library.
This is a known issue in Visual Studio 2010
Symptoms:
... when you try to build a solution with multiple
projects where there exists dependency relationships among them, in
specific conditions a build fails with the following error message.
Error Message:
“C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets
(1200, 9): warning: The referenced project 'Relative path to the
referenced project from the current directory’ does not exist.”
A build fails with the error message above when the following
conditions are met.
You have a solution with multiple projects where there exists dependency relationships among them.
The sum of the following two path length is exactly added up to 259 characters (= MAX_PATH – 1)
1) The path of a referencing project’s directory. 2) The relative path
to a referenced project from the current directory (= a referencing
project’s directory).
NOTE: MAX_PATH is the maximum path length defined by Windows API and
is set to be 260 characters.
Workaround:
To work around this issue, you can change path length and make sure
that the sum of the following two path length is NOT added up to 259
characters.
The path of a referencing project’s directory.
The relative path
to a referenced project from the current directory (= a referencing
project’s directory).
I encountered the same error recently. The solution built locally in VS2010 just fine, but consistently failed on the build server. In the end, the MSBuild definition was set to the Release x86 configuration, but the complaining project referenced an assembly in bin\x86\Debug, instead of bin\x86\Release.
Verifying the release version of the assembly was referenced instead of the debug version (and correcting as needed) seemed to do the trick for me.
The problem on my end was entirely different unfortunately.
I was building two different versions of the same common code, one for .Net4 and another for Silverlight 5, with the same file name (.Framework.dll).
Since the build server outputs everything to the same folder by default, the Silverlight version of the assembly ended up overwriting the .Net4 one because msbuild decided to build it later. This caused a problem as soon as the next project in the solution was built, which was dependent on some classes that were available on the .Net4 version of the dll, but not on the Silverlight one.
I ended up splitting the projects in multiple solutions and setting the 'Solution Specific Build Outputs' option to true on the build definition 'Process' tab.
I had a very similar issue. I found that in the Configuration Manager, under the Release Configuration, the platform was set to Any CPU and the Build checkbox was not checked.
Setting the platform to x86 (as all my other projects are set to this for legacy reasons) and making sure the project was set to Build under this configuration fixed my issue.
I've just had a similar issue and it ended up being the developer who last worked on the code decided to add references to some dlls in the obj\debug directory.
It is a bit old question but I've just come across similar issue and in my case it was the wrong referenced project Id (let's call it B) in the .cproj file of the project that was failing (project A). Originally, I copied the project A from another solution and included it in the solution I am working with now. The referenced project B was also present in both solutions so Visual Studio automatically resolved references even though in the A's .cproj referenced project B was still pointing to the B in the solution I copied it from:
<ProjectReference Include="..\B.csproj">
<Project>{F3006530-D421-4A89-AA8B-376DBAA31E03}</Project> - wrong Id!
<Name>ProjectB</Name>
</ProjectReference>
Weirdly, Visual Studio would ignore the incorrect Id and presumably use the path only so there were no build errors and correct dll would appear in project A's bin. MSBuild on my build server wouldn't be that liberal though.
To fix it you can either edit .cproj file in a text editor or simply remove references and add them back making sure they're in your current solution.

What does the "Link Library Dependency" linker option actually do in Visual Studio 2010 - 2015 and upwards?

Up to VS2008, you set your native C++ project dependencies up in the solution file (Project Dependencies ...) and if (by default) the Linker Option
Properties -> Linker -> General : Link Library Dependencies = Yes
is set, the Visual Studio Build will automatically link in the .lib files of all projects (DLLs, LIBs) that this project is dependent on will be "statically" linked in.
Side Note: Microsoft changed how the dependencies worked in VS2010 and you are now supposed to add the dependency directly to the project
Common Properties -> Framework and References : (List of depenencies)
(each lib/dll has a separate option:
Project Reference Properties -> Link Library Dependencies : True|False
I'm fine with that. This is not what this question is about.
(One explanation here: Flexible Project-to-Project References.)
It is still possible however to define project dependencies on the Solution level and the General Linker option is also still there. However it doesn't work. See:
Link Library Dependencies not working?
Did Visual Studio 2010 break "Project Dependencies" between C++ projects?
Visual Studio 2010 not autolinking static libraries from projects that are dependencies as it should be supposed to
"but oddly enough, without removing the old UI, or in any way indicating that it no longer works"
and especially see here (acutal question follows)
MS Connect Bug 586113: "Link Library Dependencies" does not work
Where Microsoft confirms that the Linker Option doesn't do what the rest of the world's population expects it to do, and adds the following explanation:
Thanks for reporting this feedback. The issue you are experiencing is
by design. "Link Library Dependency" is a flag that only dictates
whether or not to pass the library as an input to the linker. It does
not find the dependency automatically. As a customer you will have to
define the depedency manually as you suggest.
Can anyone explain what that means, or more to the point: What does the "Link Library Dependency" linker option actually do in Visual Studio 2010?
What is an "input to the linker" that isn't actually linked supposed to be?
You have to give the setting the proper value to bring clarity:
2017 Re-Run. Yay.
TL;DR
This Option sets the default value(a) for the actual Link Library Dependecies on each project reference. If each project reference has LinkLibraryDependecies set, then it is in effect meaningless.
However, when adding a new reference, by default (in VS2010 and 2015) the new <ProjectReference> element in the vcxproj file does not have the setting set, so this option is relevant in that it provides the default for all newly added references, as long as their value isn't modified.
(a): It really should be the same for all Configurations (Debug/Release) and Platforms (Win32/x64) or things get really complicated.
Gory details
Hans pointed out that it appears to not do anything in VS2010 as such. However, this doesn't mean that it actually ain't used by VS/MSBuild.
The crux is how this option is inserted into the vcxprj file and how the defaults work for the <ProjectReference> setting in the msbuild file.
The setting on the Linker dialog as shown above is inserted as:
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
...
<ItemDefinitionGroup>
<ClCompile>
...
</ClCompile>
<Link>
...
</Link>
<ProjectReference>
<LinkLibraryDependencies>This option is not used by VS 2010!</LinkLibraryDependencies>
</ProjectReference>
...
</ItemDefinitionGroup>
</Project>
And while it appears to be somehow grouped together with the Link Option, that's just there to confuse you.
What this actually does in a given vcxproj file (or when coming from a .propsfile), is to set the default value of the Link Library Dependencies Value for each project dependency on the Frameworks and References section in a VS2010 VC settings dialog --
-- or in the subtree of the VS2015 References --
And this is relevant, because when you add a new project reference, the default entry in your vcxproj file will look like this:
...
<ItemGroup>
<ProjectReference Include="..\W32DynLib1\W32DynLib1.vcxproj">
<Project>{96be134d-acb5-....-....-....bb6fe4a7}</Project>
</ProjectReference>
</ItemGroup>
You'll notice that the <LinkLibraryDependecies>true|false</..> sub element is missing here: This means you "global" setting will actually be used to set the default value.
If your global setting is false (or No), the project reference won't link in anything. If it's true, it will link in.
What's more:
If this setting, LinkLibraryDependency, is completely missing from your settings, it will default to true (from the Microsoft.Cpp[.Common].propsfile in the MSBuild folder).
If you happen to have the value This is not used in your global setting, this will be interpreted as true.
If you have the value False is the new truth!, or maybe No way in this setting, it will also be interpreted as true by the build.
The VS2015 GUI will display a warning if it cannot interpret the string here:
The VS2010 GUI will display False for ALL values, except false, even though this is then interpreted as true when building the project.
What's even more:
It seems that when converting old Solutions with vcproj files, the converter will take the old dependencies that were specified in the sln and the value of the vcproj project's Linker option, and actually set the LinkLibraryDependency for each ProjectReference it inserts into the new vcxproj - thats one reason I thought that this is a dead option for so long - most of our projects have a conversion history dating back to VS2005.
Here the thing is you have to go to, project properties -> common properties -> framework and references and then add new reference to your projects. Then only it will work in VS 2010 not like in early versions of VS
This has to be set in the Properties / Common / Frameworks and References
Alternatively you can add something like the thing below in your vcxproj file, of course use the actual project you're referencing and the uuid of that project.
<ItemGroup>
<ProjectReference Include="..\Cpp\Cpp.vcxproj">
<Project>{c58574bf-9dd8-4cf8-b5b6-6551f2f3eece}</Project>
</ProjectReference>
</ItemGroup>
It seems like you also have to set
<IgnoreImportLibrary>false</IgnoreImportLibrary>
in the REFERENCED project.

When does MSBuild set the $(ProjectName) property?

I'm fairly new to MSBuild, and I've done some customization on a WPF project file that I'm building both in Visual Studio 2010 and TFS 2010. I've customized the output path as follows:
<OutputPath Condition=" '$(TeamBuildOutDir)' == '' ">$(SolutionDir)build\binaries\$(ProjectName)\$(Configuration)\$(Platform)</OutputPath>
<OutputPath Condition=" '$(TeamBuildOutDir)' != '' ">$(TeamBuildOutDir)binaries\$(ProjectName)\$(Configuration)\$(Platform)</OutputPath>
This allows me to build to a centralized binaries directory when building on the desktop, and allows TFS to find the binaries when CI builds are running.
However, it seems that in both cases, the $(ProjectDir) property is evaluating to '' at build time, which creates strange results. Doing some debugging, it appears as if $(ProjectName) is set by the time BeforeBuild executes, but that my OutputPath property is evaluating it prior to that point.
<ProjectNameUsedTooEarly Condition=" '$(ProjectName)' == '' ">true</ProjectNameUsedTooEarly>
The preceding property is in the same property group as my OutputPath property. In the BeforeBuild target, $(ProjectNameUsedTooEarly) evaluates to true, but $(ProjectName) evaluates to the project name as normal by that point.
What can I do to ensure that $(ProjectName) has got a value when I use it?
I just used Attrice's MSBuild Sidekick to debug through my build file, and in the very first target available for breakpoint (_CheckForInvalidConfigurationAndPlatform) all the properties seem to be set already. ProjectName is already set correctly, but my OutputPath property has already been set using the blank value of ProjectName.
Hmm - bit of confusion going on there which I'll try to sort out
Don't use $(ProjectDir) - use $(MSBuildProjectDir) - that's the location of your csproj in the source tree and is set by MSBuild.exe as a reserved property. I don't think $(ProjectDir) is available until after Microsoft.Common.Targets has been imported (which is done by Microsoft.Csharp.targets). Property evaluation is always carried out "in-place" within the file, and not when all the Imports have completed. This may explain why you are seeing the property as valid in the SideKick tool
Likewise use $(MSBuildProjectName) (which I think will address your problem)
I'm unsure about VS2010 and TFS2010 (as that uses MSBuild 4.0 and no doubt a new TeamBuild), but in 2008, it's pretty hard within a .csproj to figure out if your build was called from a command line/IDE build or from within TeamBuild. What I'm trying to say is that I don't think $(TeamBuildOutDir) is available within your csproj. I normally test $(TeamBuildConstants) property, as that property is passed down when teambuild calls your proj file. YMMV as I haven't played with 2010 yet..

MSBuild doesn't copy references (DLL files) if using project dependencies in solution

I have four projects in my Visual Studio solution (everyone targeting .NET 3.5) - for my problem only these two are important:
MyBaseProject <- this class library references a third-party DLL file (elmah.dll)
MyWebProject1 <- this web application project has a reference to MyBaseProject
I added the elmah.dll reference to MyBaseProject in Visual studio 2008 by clicking "Add reference..." → "Browse" tab → selecting the "elmah.dll".
The Properties of the Elmah Reference are as follows:
Aliases - global
Copy local - true
Culture -
Description - Error Logging Modules and Handlers (ELMAH) for ASP.NET
File Type - Assembly
Path - D:\webs\otherfolder\_myPath\__tools\elmah\Elmah.dll
Resolved - True
Runtime version - v2.0.50727
Specified version - false
Strong Name - false
Version - 1.0.11211.0
In MyWebProject1 I added the reference to Project MyBaseProject by:
"Add reference..." → "Projects" tab → selecting the "MyBaseProject". The Properties of this reference are the same except the following members:
Description -
Path - D:\webs\CMS\MyBaseProject\bin\Debug\MyBaseProject.dll
Version - 1.0.0.0
If I run the build in Visual Studio the elmah.dll file is copied to my MyWebProject1's bin directory, along with MyBaseProject.dll!
However if I clean and run MSBuild for the solution (via D:\webs\CMS> C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe /t:ReBuild /p:Configuration=Debug MyProject.sln)
the elmah.dll is missing in MyWebProject1's bin directory - although the build itself contains no warning or errors!
I already made sure that the .csproj of MyBaseProject contains the private element with the value "true" (that should be an alias for "copy local" in Visual Studio):
<Reference Include="Elmah, Version=1.0.11211.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\mypath\__tools\elmah\Elmah.dll</HintPath>
**<Private>true</Private>**
</Reference>
(The private tag didn't appear in the .csproj's xml by default, although Visual Studio said "copy local" true. I switched "copy local" to false - saved - and set it back to true again - save!)
What is wrong with MSBuild? How do I get the (elmah.dll) reference copied to MyWebProject1's bin?
I do NOT want to add a postbuild copy action to every project's postbuild command! (Imagine I would have many projects depend on MyBaseProject!)
I just deal with it like this. Go to the properties of your reference and do this:
Set "Copy local = false"
Save
Set "Copy local = true"
Save
and that's it.
Visual Studio 2010 doesn't initially put:
<private>True</private> in the reference tag and setting "copy local" to false causes it to create the tag. Afterwards it will set it to true and false accordingly.
I'm not sure why it is different when building between Visual Studio and MsBuild, but here is what I have found when I've encountered this problem in MsBuild and Visual Studio.
Explanation
For a sample scenario let's say we have project X, assembly A, and assembly B. Assembly A references assembly B, so project X includes a reference to both A and B. Also, project X includes code that references assembly A (e.g. A.SomeFunction()). Now, you create a new project Y which references project X.
So the dependency chain looks like this: Y => X => A => B
Visual Studio / MSBuild tries to be smart and only bring references over into project Y that it detects as being required by project X; it does this to avoid reference pollution in project Y. The problem is, since project X doesn't actually contain any code that explicitly uses assembly B (e.g. B.SomeFunction()), VS/MSBuild doesn't detect that B is required by X, and thus doesn't copy it over into project Y's bin directory; it only copies the X and A assemblies.
Solution
You have two options to solve this problem, both of which will result in assembly B being copied to project Y's bin directory:
Add a reference to assembly B in project Y.
Add dummy code to a file in project X that uses assembly B.
Personally I prefer option 2 for a couple reasons.
If you add another project in the future that references project X, you won't have to remember to also include a reference to assembly B (like you would have to do with option 1).
You can have explicit comments saying why the dummy code needs to be there and not to remove it. So if somebody does delete the code by accident (say with a refactor tool that looks for unused code), you can easily see from source control that the code is required and to restore it. If you use option 1 and somebody uses a refactor tool to clean up unused references, you don't have any comments; you will just see that a reference was removed from the .csproj file.
Here is a sample of the "dummy code" that I typically add when I encounter this situation.
// DO NOT DELETE THIS CODE UNLESS WE NO LONGER REQUIRE ASSEMBLY A!!!
private void DummyFunctionToMakeSureReferencesGetCopiedProperly_DO_NOT_DELETE_THIS_CODE()
{
// Assembly A is used by this file, and that assembly depends on assembly B,
// but this project does not have any code that explicitly references assembly B. Therefore, when another project references
// this project, this project's assembly and the assembly A get copied to the project's bin directory, but not
// assembly B. So in order to get the required assembly B copied over, we add some dummy code here (that never
// gets called) that references assembly B; this will flag VS/MSBuild to copy the required assembly B over as well.
var dummyType = typeof(B.SomeClass);
Console.WriteLine(dummyType.FullName);
}
If you are not using the assembly directly in code then Visual Studio whilst trying to be helpful detects that it is not used and doesn't include it in the output. I'm not sure why you are seeing different behaviour between Visual Studio and MSBuild. You could try setting the build output to diagnostic for both and compare the results see where it diverges.
As for your elmah.dll reference if you are not referencing it directly in code you could add it as an item to your project and set the Build Action to Content and the Copy to Output Directory to Always.
Take a look at:
This MSBuild forum thread I started
You will find my temporary solution / workaround there!
(MyBaseProject needs some code that is referencing some classes (whatever) from the elmah.dll for elmah.dll being copied to MyWebProject1's bin!)
I had the same problem.
Check if the framework version of your project is the same of the framework version of the dll that you put on reference.
In my case, my client was compiled using "Framework 4 Client" and the DLL was in "Framework 4".
The issue I was facing was I have a project that is dependent on a library project. In order to build I was following these steps:
msbuild.exe myproject.vbproj /T:Rebuild
msbuild.exe myproject.vbproj /T:Package
That of course meant I was missing my library's dll files in bin and most importantly in the package zip file. I found this works perfectly:
msbuild.exe myproject.vbproj /T:Rebuild;Package
I have no idea why this work or why it didn't in the first place. But hope that helps.
I just had the exact same problem and it turned out to be caused by the fact that 2 projects in the same solution were referencing a different version of the 3rd party library.
Once I corrected all the references everything worked perfectly.
As Alex Burtsev mentioned in a comment anything that’s only used in a XAML resource dictionary, or in my case, anything that’s only used in XAML and not in code behind, isn't deemed to be 'in use' by MSBuild.
So simply new-ing up a dummy reference to a class/component in the assembly in some code behind was enough convince MSBuild that the assembly was actually in use.
Using deadlydog's scheme,
Y => X => A => B,
my problem was when I built Y, the assemblies (A and B, all 15 of them) from X were not showing up in Y's bin folder.
I got it resolved by removing the reference X from Y, save, build, then re-add X reference (a project reference), and save, build, and A and B started showing up in Y's bin folder.
Changing the target framework from .NET Framework 4 Client Profile to .NET Framework 4 fixed this problem for me.
So in your example: set the target framework on MyWebProject1 to .NET Framework 4
I had the same problem and the dll was a dynamically loaded reference.
To solve the problem I have added an "using" with the namespace of the dll.
Now the dll is copied in the output folder.
This requires adding a .targets file to your project and setting it to be included in the project's includes section.
See my answer here for the procedure.
Referencing assemblies that are not used during build is not the correct practice. You should augment your build file so it will copy the additional files. Either by using a post build event or by updating the property group.
Some examples can be found in other post
MSBuild to copy dynamically generated files as part of project dependency
VS2010 How to include files in project, to copy them to build output directory automatically during build or publish
Another scenario where this shows up is if you are using the older "Web Site" project type in Visual Studio. For that project type, it is unable to reference .dlls that are outside of it's own directory structure (current folder and down). So in the answer above, let's say your directory structure looks like this:
Where ProjectX and ProjectY are parent/child directories, and ProjectX references A.dll which in turn references B.dll, and B.dll is outside the directory structure, such as in a Nuget package on the root (Packages), then A.dll will be included, but B.dll will not.
I had a similar issue today, and this is most certainly not the answer to your question. But I'd like to inform everyone, and possibly provide a spark of insight.
I have a ASP.NET application. The build process is set to clean and then build.
I have two Jenkins CI scripts. One for production and one for staging. I deployed my application to staging and everything worked fine. Deployed to production and was missing a DLL file that was referenced. This DLL file was just in the root of the project. Not in any NuGet repository. The DLL was set to do not copy.
The CI script and the application was the same between the two deployments. Still after the clean and deploy in the staging environment the DLL file was replaced in the deploy location of the ASP.NET application (bin/). This was not the case for the production environment.
It turns out in a testing branch I had added a step to the build process to copy over this DLL file to the bin directory. Now the part that took a little while to figure out. The CI process was not cleaning itself. The DLL was left in the working directory and was being accidentally packaged with the ASP.NET .zip file. The production branch never had the DLL file copied in the same way and was never accidentally deploying this.
TLDR; Check and make sure you know what your build server is doing.
Make sure that both projects are in the same .net version also check copy local property but this should be true as default
Using Visual Studio 2015 adding the additional parameter
/deployonbuild=false
to the msbuild command line fixed the issue.
I just ran into a very similar issue. When compiling using Visual Studio 2010, the DLL file was included in the bin folder. But when compiling using MSBuild the third-party DLL file was not included.
Very frustrating. The way I solved it was to include the NuGet reference to the package in my web project even though I'm not using it directly there.
I dont think #deadlydog answer is valid with the current Nuget system. I recreated the scenario with Y => X => A => B in visual studio 2022 and all I had to do was run the command in terminal
msbuild -t:clean,rebuild,pack
Including all referenced DLL files from your projectreferences in the Website project is not always a good idea, especially when you're using dependency injection: your web project just want to add a reference to the interface DLL file/project, not any concrete implementation DLL file.
Because if you add a reference directly to an implementation DLL file/project, you can't prevent your developer from calling a "new" on concrete classes of the implementation DLL file/project instead of via the interface. It's also you've stated a "hardcode" in your website to use the implementation.

Visual Studio msbuild

I have a question regarding the commandline options of msbuild. I am
currently using msbuild to build projects using the existing solution
files. These solution files have references to external dll which have
different paths on each machine. I am currently writing a build script
and passing the specific path to the project file via the /p: switch of
msbuild.
My current build line is:
msbuild test.sln /p:ReferencePath="c:\abc" /p:ReferencePath="c:\rca"
What i have noticed that Reference Path now contains only c:\rca and
not c:\abc. this is causing problems for me since, the external dlls
lie in two different directorys. I am allowed to keep multiple
reference paths via visual studio, but not via the commandline.
Is there any known way by which i can do this
I believe you can use this /p:ReferencePath="c:\abc;c:\rca"
At least that is what that link is hinting at, they are using %3B to encode the ";" within the build file.
Although the correct syntax for providing more the one reference path is listed above, I would suggest solving the root cause which in my opinion is the different locations of your referenced assembly. I would suggest you put all thirdparty dependencies, apart from the framework assemblies in your source code repository for the following reasons:
Relatitve paths are consistent across computers
The source code is always in sink with the correct version of your thirdparty assembly (if you for instance need to build an old version of your software 2 years from now).
Upgrading your thirdparty assembly is as easy as upgrading on one machine and then committing your changes to the repository. (In a previous project we even went as far as checking in the entire java runtime environment and were quite happy with the given setup.)
Try seperating your pathes with a semi-colon (;)
Like this:
c:\abc;c:\rca
You may be better off by synchronizing your libraries across machines. I have found that Visual Studio makes this easy. Simply add a solution folder, and add your libraries there. Then, in each project, reference the libraries from this common place. This way, each developer has them in the same place.
This will remove one of variables you have when trying to script out builds.
The command line options for setting the reference path will work just fine (assuming you escape the semi colon, it seems both %3B and ; will work). However, when the argument was passed in from nant (and I needed multiple paths), creating a 'Visual Studio Project User Options file' seemed to work better.
I just emit (echo) a file to the file system with the following format:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ReferencePath>
C:\abc;c:\rca
</ReferencePath>
</PropertyGroup>
I give the *.user file an appropriate name (given a project file MyProject.csproj, my user file would be MyProject.csproj.user)

Resources