phmonte / Buildalyzer

A utility to perform design-time builds of .NET projects without having to think too hard about it.
MIT License
593 stars 94 forks source link

Get an adhocworkspace from an already built solution that I can compile/emit? #127

Closed MilleBo closed 4 months ago

MilleBo commented 4 years ago

Hey,

I'm currently in the process of moving some logic from a visual studio extension to a separate application and have a couple of questions.

In general I just want to open a solution, generate some code and then compile with roslyn which work perfect with VisualStudioWorkspace but it seems to be a bigger problem with MsBuildWorkspace/AdHocWorkspace.

I started with a simple MsBuildWorkspace/MsBuild.Locator but it seem to fail from time to time of different reasons so I decided to try your project (which seems awesome).

My first try was with DesignTime true but this doesn't work at all (which is expected I guess) and I get a lot of "The type 'x' is defined in an assembly that is not referenced" or "The type or namespace name 'x' could not be found".

My next try was to simply set DesignTime false and now it build/compile fine. The problem is that in most cases I have already pre-built the solution so clean/build is unnecessary and it is very time consuming (I had a solution that took over 10 min to build which seems crazy).

My next step was to remove "Clean" so it only did a build. This of course goes much faster but then I checked the current solution inside the adHocWorkspace and every project have 0 documents (can't see any errors in the build logs either). Any idea why?

But in general my question is this:

What is the easiest/fastest way to load the adhocworkspace from an already built solution that still make it possible to compile/emit with roslyn?

This is my current solution with clean that gives me zero documents:

            var log = new StringWriter();
            var analyzerOptions = new AnalyzerManagerOptions
            {
                LogWriter = log
            };

            var manager = new AnalyzerManager(solutionPath, analyzerOptions);
            using (var workspace = new AdhocWorkspace())
            {
                var environmentOptions = new EnvironmentOptions { DesignTime = false };
                environmentOptions.TargetsToBuild.Remove("Clean");

                foreach (var projectKeyValue in manager.Projects)
                {
                    var project = projectKeyValue.Value;
                    var results = project.Build(environmentOptions);

                    results.Results.First().AddToWorkspace(workspace);
                }

                return await Task.FromResult(workspace.CurrentSolution);
            }
        }
MilleBo commented 4 years ago

I did some more research on the no document thing and it seems to be because we don't get any MessageRaisedevents in EventProcessor when we remove clean. Because of that we never set _cscCommandLineArguments in AnalyzerResult to a value and later on can't get any documents.

Is it possible to get around it somehow? Will otherwise try to look some more later.

phmonte commented 4 months ago

Hello @MilleBo, Did you have any news?

phmonte commented 4 months ago

Closing the issue due to lack of feedback, if the problem persists, please open a new one.