Maybe I am overlooking something here but I can't seem to find a good way to parse a solution file and programmatically exclude some projects (.vcxproj) from the build. Many SO posts reference the SolutionFile class in Microsoft.Build.Construction to enumerate the list of projects and their configurations. In fact there is even a IncludeInBuild property that tells me if a particular configuration is selected to be included in the build (see: https://msdn.microsoft.com/en-us/library/microsoft.build.construction.projectconfigurationinsolution.includeinbuild.aspx)
However I can't seem to find a way to alter/create-a-copy-of the solution file and do a moral equivalent of setting the IncludeInBuild property to false for some projects.
Is this not possible today?
Related
I have some older projects in non-SDK style which were created using Visual Studio; the csproj files were almost never modified manually. They were done partly by colleages before I came to this company, so I have very incomplete knowledge about what should or shouldn't be in these files.
Now I am trying to turn them into SDK-style projects by manually modifying the csproj files. In order to do that, I need to understand for each tag what it is for, and if it can be omitted or must be modified.
There might be
non-SDK-style leftovers that can just be deleted,
content we were not aware of (because we don't always know what we are doing when playing around with settings in a project),
content that needs to be modified to fit the new SDK-style specification,
content that can be omitted because it contains just its default value,
etc.
I try getting by by googling a given tag together with "csproj", but more often than not I cannot find useful content. I also noticed that most of the time I DO NOT find a source from Microsoft, mostly blog entries by private guys that sometimes, sometimes not tell me what I want to know.
There are some Microsoft docs like sdk reference or common properties, but they do not cover all tags that I have in my project.
So, how can I understand the content of my csproj file? Is the documentation there and I am merely not finding it? If so, what to search for? Shouldn't Microsoft have a comprehensive list of all possible tags? They have invented the csproj format, so they should know. Or do I need to learn something else first that is a prerequisite of working with csproj files (like before constructing bridges one should know about basic algebra and calculus), that will help me figure out stuff on my own?
cproj files can have a lot of project configurations. Visual Studio Extensions might also modify cproj files and add custom values.
As per the comments on this answer, there isn't a complete list of available properties for Visual Studio projects. The links provided in the question contains most used properties, so that should cater for the average project.
It is very rare that properties will be used that is not contained in those links. If you do run across an unknown property, try searching online, if that fails, ask on SO.
A good search query that hasn't failed me yet, {Project Type} "{Property}" csproj property : .Net "TestProjectType" csproj property.
I have a need to identify if I'm referencing a specific assembly in my project/solution. I've not found an easy way to do this (I want to do it at design time and not run time if possible).
Seems this should be easy, but I'm not finding a way in VS, directly. Ideally, if I could see what/where I'm referencing (assuming that I am) would be great, too, so I can remove such references from my code.
Simply searching for "Assembly." in my code turns up nothing, now, for example.
A concrete example is in order: I want to know if I use anything in System.Reflection.Assembly. And I'd like to find the code that does it (in my source) if I do.
Do you want something like Assembly.GetReferencedAssemblies Method ?
http://msdn.microsoft.com/en-us/library/system.reflection.assembly.getreferencedassemblies(v=vs.110).aspx
In Visual Studio (almost all versions) open the Solution Explorer window the second "folder" is the References section. If you expand that you'll be able to see the referenced assemblies.
Image from robowiki
The project that I'm currently working on is being developed by multiple teams where each team is responsible for different part of the project. They all have set up their own C# projects and solutions with configuration settings specific to their own needs. However, now we need to create another, global solution, which will combine and build all projects into the same output directory.
The problem that I have encountered though, is that I have found only one way to make all projects build into the same output directory - I need to modify configurations for all of them. That is what we would like to avoid. We would prefer that all these projects had no knowledge about this "global" solution. Each team must retain possibility to work just with their own sub-solution.
One possible workaround is to create a special configuration for all projects just for this "global" solution, but that could create extra problems since now you have to constantly sync this configuration settings with the regular one, used by that specific team. Last thing we want to do is to spend hours trying to figure out why something doesn't work when building under global solution just because of some check box that developers have checked in their configuration, but forgot to do so in the global configuration.
So, to simplify, we need some sort of output directory setting or post build event that would only be present when building from that global, all-inclusive solution. Is there any way to achieve this without changing something in projects configurations?
Update 1
Some extra details I guess I need to mention:
We need this global solution to be as close as possible to what the end user gets when he installs our application, since we intend to use it for debugging of the entire application when we need to figure out which part of the application isn't working before sending this bug to the team working on that part.
This means that when building under global solution, the output directory hierarchy should be the same as it would be in Program Files after installation, so that if, for example, we have Program Files/MyApplication/Addins folder which contains all the addins developed by different teams, we need the global solution to copy the binaries from addins projects and place them in the output directory accordingly.
The thing is, the team developing an addin doesn't necessary know that it is an addin and that it should be placed in that folder, so they cannot change their relative output directory to be build/bin/Debug/Addins.
The key here is that team is responsible for a deliverable. That deliverable is a collection of binaries. So the "global" solution ... or "product that uses the deliverables from teams" is interested in ensuring that all of the 'current deliverables' work together. That is, that you have a deliverable from the collaborative effort.
So this begs a few questions. Do the team deliver what they consider to be a 'release'. This may be automatic in the build system. If it builds and all tests pass then publish it.
What you are looking for is a team publishing or promoting a release. The source code is how you got there, the binaries are the result. Each team controls what binaries it considers to be a release (this may be automated by the build system).
Not exactly what you asked, but I hope it is the answer that leads to the right questions to give good results.
One very simple way would be to create the solution. Include all the projects and add a project (or more) to handle the global solution build tasks. The projects in the global solution should then have a reference to the projects they need and then let Visual Studio handle how to get the binaries from each project. They will (under normal circumstances) be copied to the output folder of the build project. So the project added specifically for the global build tasks would have a copy of all the referenced projects
Another way would be to create a global MSBuild script that references the rest of the build scripts. Each project is on it's own a MSBuild script
EDIT
From the comments it would seem that there are two categories of projects. One that needs building and one that does not.
For those that need building reference them as projects in the aggregating project for those that do not require building add them either as references or add the dll as resources.
Using the later change the property of the Build action to None and copy to output directory to Copy if newer
In both cases you now have all dll's in the output directory you can then have a post build action on the aggregating project moving the dlls that should be in a specific folder (ie not in the output folder)
Have a look at the practice of Continuous Integration and the usage of a Build Server with scripted builds. This is an indispensable instrument when developing different parts of an application as a team, and your problems are a great illustration of the reason why.
You've not mentioned if you use a Version Control system. I've found in practise that each developer maintains his/hers/their teams configuration and builds locally on there machine, since you don't check *.suo or *.user files most of the personal configuration only affects the individual team member.
On a completely seperate machine check-out the same code from all repositories and compile the project on the build machine (this can be completely automated). This maintains your build servers independance.
Don't worry about it being a "Solution". You can easily build multiple solutions one after the other.
Since the output path is relative (and probably "bin\Debug") it'll get built wherever you check it out to. If you want all the binaries in the same output folder you could tweak the output path on every configuration to match. Something like "....\bin\Debug" (obviously this affects where the projects get built to on the local machines but it might not matter). That way multiple projects would get built the same target output.
You could also include a seperate setup build on the build server which isn't on each developers local machine to package up the final product.
We're trying to switch a lot of projects over to use SDK7.1. This seems pretty straightforward with C++ projects, and you can change the 'Platform Toolset' property in the project settings to "Windows7.1SDK" and all is good.
But, with C# projects, (if you put the build output up to diagnostic mode), we can see that various tools such as sgen, resgen, LC, run from within a previous SDK 7.0A directory. Or, on some machines that we installed Vistual Studio 2012 on, some of these tools come from an v8.0A SDK folder.
Mismatches between the tools and the assemblies they produce seem to be causing various errors such as:
LC : error LC0000: 'Could not load file or assembly
'S:\Libraries\Bin\Release\Some.dll' or one of its dependencies. This assembly is built by a runtime newer than the currently loaded runtime and cannot be loaded.'
It seems we can edit the .csproj files and almost ad-hoc, and BeforeBuild etc targets that redefine various SDKPath properties. This seems to force the right tools to be used. But, if feels very 'hacky'. And we must be missing setting something as we still get some errors.
Alternatively, we've found, we can change the registry value here:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\4.0\SDK40ToolsPath
to point at the correct SDK. But, it feels wrong to have to modify the environment to support this. We want to build old versions of our product, and having to switch the environment around to do this is ugly and error prone.
Is there any official way of doing this?
Thanks.
P.S. I found this question http://social.msdn.microsoft.com/Forums/en-MY/windowssdk/thread/ebc8914f-d4b5-44e7-8c76-10332d155812 where the poster seems to be asking a similar thing, but, the question didn't seem to get answered.
The following two articles talk about defining custom tool sets. Perhaps one of those needs defining for the 7.1 SDK, and then MSBuild can be directed to use it.
http://msdn.microsoft.com/en-us/library/bb383796(v=vs.110).aspx
http://msdn.microsoft.com/en-us/library/bb397428.aspx
I realize that this is not the best practices for working on individual projects. However, I had a rather large code base I am attempting to refactor, and would like to know if a change I make has modified/broken any number of existing projects.
Is there a way to add all existing projects within a specific directory to a single solution within visual studio?
If not, is there another way I could do this without manually adding each project?
I do not believe there is a method in the box.
But if it's really going to be that tedious of a task I would use PowerShell to search the directory for a files with the csproj extension, and output a bunch of "Project" statements (along with generation of unique identifiers) that you can copy/paste into your Solution file.