In a MSBuild file how to I get the referenced projects? - c#

I have a MSBuild script file and I want to perform an action for each projects that were imported in the file.
How do I get access to the referenced projects ?

It is not clear what kind of action you want to perform on each project. Assuming you want simply to print out the paths of referenced projects, here is the sample code:
Dictionary<string, string> globalProperties = new Dictionary<string, string>();
globalProperties.Add("Configuraion", "Debug");
globalProperties.Add("Platform", "AnyCPU");
ProjectCollection pc = new ProjectCollection(globalProperties);
Project sln = pc.LoadProject(#"MyProject.csproj", "4.0");
foreach (ProjectItem pi in sln.Items)
{
if (pi.ItemType == "ProjectReference")
{
Console.WriteLine(pi.EvaluatedInclude);
}
}
The code above uses ProjectCollection and Project types from Microsoft.Build.dll, which is part of MSBuild.
Note, that in theory project references depend on build parameters, e.g. you might reference debugging library for Debug configuration, but not for release. Therefore while initializing ProjectCollection you have to pass parameters you want.

Related

Roslyn - determine project excluded from build configuration

I am trying to figure out which project is enabled/disabled in respective build configuration/platform setup. Where could I find this "project.BuildsInCurrentConfiguration" information please?
var properties = new Dictionary<string, string>
{
{ "Configuration", "Debug" },
{ "Platform", "x86"}
};
MSBuildWorkspace workspace = MSBuildWorkspace.Create(properties);
workspace.LoadMetadataForReferencedProjects = true;
Solution solution = workspace.OpenSolutionAsync("someSolution.sln").Result;
foreach (Project project in solution.Projects)
Console.Out.WriteLine($"{project.OutputFilePath} is enabled in this build setup: {project.BuildsInCurrentConfiguration}");
workspace.CloseSolution();
I would have thought I wouldn't be offered the projects that are not part of the picked configuration/platform, but solution.Projects shows me all of them regardless build setup.
I don't think Roslyn really has most of that information right now (I'm not sure if it ever would; but I would hope it would). I don't see anything related to a "configuration" for a project with the Roslyn APIs for example. That seems to be delegated to the DTE interfaces. You can get at platform type in a Roslyn project, so conceptually you could only get projects that would apply to a given type of build:
var rolsynProjects = solution.Projects
.Where(p => p.CompilationOptions.Platform == Platform.X86);
but, things like "DEBUG" configuration seem to only be available via DTE--which isn't that hard to get at. e.g.
var project = DTE.Solution.Projects
.Where(p=>p.FullName == rolsynProjects.First().FilePath).FirstOrDefault();
And from that VS project, you can get at its ConfigurationManager

roslyn project configuration

I am using Microsoft.CodeAnalysis and .MSBuild to load up solution, it's projects and retrieve project OutputFilePath. Trouble is Debug and Release have different ones and I can't figure out a way to switch between solution configurations. Any idea how to set which configuration will be used?
MSBuildWorkspace workspace = MSBuildWorkspace.Create();
workspace.LoadMetadataForReferencedProjects = true;
Solution solution = workspace.OpenSolutionAsync("someSolution.sln").Result;
foreach (Project project in solution.Projects)
Console.Out.WriteLine(project.OutputFilePath);
workspace.CloseSolution();
Some MSBuild properties, like typically the output path, depend on the configuration that the project is built with. You have to specify that configuration when you create the workspace.
For example:
var properties = new Dictionary<string, string>
{
{ "Configuration", "Debug" } // Or "Release", or whatever is known to your projects.
// ... more properties that could influence your property,
// e.g. "Platform" ("x86", "AnyCPU", etc.)
};
MSBuildWorkspace workspace = MSBuildWorkspace.Create(properties);
workspace.LoadMetadataForReferencedProjects = true;
Solution solution = workspace.OpenSolutionAsync("someSolution.sln").Result;
foreach (Project project in solution.Projects)
Console.Out.WriteLine(project.OutputFilePath);
workspace.CloseSolution();

CSharpCodeProvider: Referencing a different version of referenced assembly

Suppose Project Main has a reference to Project Ref. In Main, I have defined a CSharpCodeProvider and use it to compile code at runtime.
var provider = new CSharpCodeProvider(new Dictionary<string, string> { { "CompilerVersion", "v4.0" } });
var parameters = new CompilerParameters();
parameters.ReferencedAssemblies.Add("System.dll");
// Rest of the referenced assemblies.
The code which is compiled at runtime, might require a newer version of Project Ref to run correctly. So I tried to add the new Ref.Dll in a relative subfolder (plugins):
parameters.ReferencedAssemblies.Add(#"d:\project-output-path\plugins\Ref.dll");
I have also added the following:
AppDomain.CurrentDomain.AppendPrivatePath("plugins");
Problem is when I try to compile the script dynamically, the Ref.dll in the main folder is being used and causes error.
So, What would be the best way to reference the new Ref project only for my script?
P.S. I really prefer not having to create another AppDomain since the dynamically executing code is coupled with the code loaded in current AppDomain and cannot be separated.

Resolving .vcxproj dependencies with c# project class doesn't return included folders

I'm trying to write a tool which will resolve dependencies between c++ and c# projects.
When I try to get folders included in vcxproj, it returns everything but included folders.
I searched, where I would expect to find them:
ItemDefinitions -> ClCompile -> AdditionalIncludeDirectories
But they are not there, or anywhere else.
Project proj = new Project(projectFileName);
ProjectItemDefinition tp = proj.ItemDefinitions.First(pid =>
String.Compare(pid.Key,"ClCompile", true) == 0).Value;
ProjectMetadata tpPMD = tp.Metadata.First(pmd =>
String.Compare(pmd.Name,"AdditionalIncludeDirectories", true) == 0);
As I know, C# project and C++ project have different object. If you want to get the VC++ project you should reference VCProject and VCProjectEngine.
Here is an example about how to get the VC project you can refer to:
http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.vcprojectengine.vcproject.aspx

Visual Studio Addin "Exclude From Build" Property

I am currently trying to create an addin for Visual Studio 2008 that will list all files which are not excluded from the current build configuration.
I currently have test C++ console application that has 10 files, 2 of which are "Excluded From Build". This is a property that will allow a specific file to be excluded from a specific configuration (i.e. Debug or Release). This property is located when you right click on a file in the solution explorer and select Properties->Configuration Properties->General->Excluded From Build
At the moment I have the following code that will loop though all project files and get the properties for each file.
foreach (Project theProject in _applicationObject.Solution.Projects)
{
getFiles(theProject.ProjectItems);
}
private void getFiles(ProjectItems theItems)
{
foreach (ProjectItem theItem in theItems)
{
string theItemName = theItem.Name;
foreach (Property theProp in theItem.Properties)
{
string thePropName = theProp.Name;
}
getFiles(theItem.ProjectItems);
}
}
The issue I am having is that I cant seem to find the "Excluded From Build" property. I cannot find very good documentation on what properties are listed where. Where is this Excluded From Build property located within the _applicationObject object?
I'm not familiar with the Visual Studio object model, but in the documentation for VS2005 the following objects have an ExcludedFromBuild property:
VCFileConfiguration
VCFileConfigurationProperties
VCPreBuildEventTool
VCPreLinkEventTool
VCPostBuildEventTool
VCWebDeploymentTool
Hopefully this will lead you down the right path.

Categories