Closed jairbubbles closed 3 years ago
Thank you for your submission, we really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
:x: jairbubbles sign now
You have signed the CLA already but the status is still pending? Let us recheck it.
This looks interesting, but I'm not sure it's the right direction. What motivated you to put this together?
My concern is that .NET Core MSBuild cannot run all the tasks and targets used by Visual Studio, and a .NET Core/.NET 5.0 application shouldn't load the full-.NET-Framework copy of MSBuild from a Visual Studio installation--it has functionality that isn't supported on .NET Core.
Hi @rainersigwald!
We use the lib to inspect .csproj
and gather properties (such as OutputPath
) and/or items (such as the PackageReferences
). In the past we used to do that by parsing the .xml but with the new toolset we now need MsBuild to evaluate the projects for us.
The main usage is to add external steps during CI (for instance to tag assemblies). We could do that directly in MsBuild targets but we prefer to rely on an external tool (for different reasons). One other scenario is a simple tool that display a graph of the dependencies of any .csproj
.
We're migrating all our tools to .NET 5.0 and we still want those tools to be able to inspect .NET Framework projects. We can imagine that at some point we won't have anymore .NET Framework .csproj to inspect but it will take some time to achieve.
We're migrating all our tools to .NET 5.0 and we still want those tools to be able to inspect .NET Framework projects.
Unfortunately that's not currently possible. If you want to be able to load any project that Visual Studio can open/MSBuild.exe can build, your application must target .NET 4.7.2 (or 4.8). MSBuild itself is in the same boat, because VS itself is a .NET Framework application.
Makes sense, invoking MsBuild has always been a challenge so I'm not really surprised it's not working with .NET Core 😅
Could we imagine adding a new command to MsBuild.exe that would exports the project after evaluation?
I know about the .binlog but they are used when compiling and we want the evaluation to be as fast as possible. We don't need to execute targets.
@jairbubbles what do you mean by "exports the project after evaluation"? Something like the current preprocessor, or do you want something like dotnet/msbuild#3911?
I'm going to close this PR, but we can keep talking.
Hi @rainersigwald,
I don't know what you mean by "current processor" as for dotnet/msbuild#3911 it does look similar to what I have in mind even I though more of a "evaluate everyhting and dump the result" so I can process it afterwards.
To better explain my needs, I'll show you bits of our library (which sadly is not public).
A basic example would look like this:
var project = new CsProject("<full_path>.csproj"); // Load a .csproj
// Get info from all the possible outputs (handle multitargetting for instance)
var outputs = project.GetAllOutputs("Release|AnyCpu");
// Get all referenced NuGet packages
var packageReferences = project.GetPackageReferences();
//...
It handles .vcxproj and .csproj, the common interface looks like this:
public interface IProject
{
string ToolsetVersion { get; }
OutputType OutputType { get; }
IEnumerable<string> Configurations { get; }
IEnumerable<string> Platforms { get; }
ProjectOutput GetOutput(string configuration = "");
ProjectOutput GetOutput(string configuration, string platform);
IEnumerable<ProjectOutput> GetAllOutputs();
IEnumerable<ProjectReference> GetProjectReferences();
string GetProperty(string propertyName);
string GetProperty(string propertyName, string configuration, string platform);
IEnumerable<string> GetSourceFiles(string configuration = "", string platform = "");
IEnumerable<FileItem> GetAllFileItems(string configuration = "", string platform = "");
string FilePath { get; }
}
So basically it's a wrapper over MsBuild to provide a simple API for scripts writers.
Ok I found the command line arguments (-preprocess
). It should indeed allow us to do what we want:
Thx for the tip @rainersigwald!
I tested quickly and sadly it didn't went as well as expected 😥
xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
in the preprocessed file and MsBuild doesn't like this when loading the project => removing them will fix the parsing so it's no big deal.TargetPath
for instance)Clean
target. @rainersigwald When we load/evaluate the properties, it runs some targets by default?There is a circular dependency in the target dependency graph involving target "DispatchToInnerBuilds"
There is a circular dependency in the target dependency graph involving target "Clean"
Hi @KirillOsenkov , by any chance I was wondering if you think we could use binlog to output the info about a .csproj, and reads them from the binlog as if we were loading the project with MsBuild directly.
msbuild.exe /bl /t:clean <my_project.csproj>
=> open my_project.binlog in our lib
=> introspect the .csproj (as shown in a prevous comment)
Also, do you know an even more mimimalistic target than "Clean" that would preprocess properly the projects and set properties such as TargetPath
, OutputPath
and so on used by the "Build" target?
Humm looks like I forgot about multitargetting when testing the preprocess commandline arguments.
By providing the framework -p:TargetFramework=net472
I'm able to get all the info I need. I'll need to test more but it's promising!
@jairbubbles yes, you can read the .binlog programmatically via an API and extract property and item values etc.
See here: https://msbuildlog.com/#api
Properties and Items will be on the ProjectStartedBuildEventArgs.
Microsoft.VisualStudio.Setup.Configuration.Interop
so not really ready to be mergednetcoreapp3.1
so that it compiles correcly