1

I'm developing a Visual Studio Extension for code analysis, the extension require to emit dll for user selected project, I have selected Microsoft.CodeAnalysis library to emit build artifact for selected project.

I was unable to find a way to open the current solution without specifying the path to sln file (added the sample code), How to get current sln path? any alternative approach to generate build artifact for selected project?

Edit: My use case: User open the VS IDE -> Open a .cs file -> he select "Analyze" option which will be added from my extension -> then the extension should compile the project which contains user opened .cs file.

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.MSBuild;

using (var workspace = MSBuildWorkspace.Create())
{
    //Open current solution
    var solution = workspace.OpenSolutionAsync("C:\test\abc.sln").Result;

    //Select the project user is working on and build it
    //
}

2 Answers 2

2

If you're trying to get the workspace for currently open project you should not use MSBuildWorkspace. Instead, MEF import VisualStudioWorkspace. That's kept live and up-to-date with the code the user is editing. See questions like this one for further details.

Sign up to request clarification or add additional context in comments.

Comments

1

How to get current sln path?

You can get current sln via Dte.Solution.FullName method, like this:

 DTE2 dte = (DTE2)this.ServiceProvider.GetService(typeof(DTE));
            ConfigurationManager configmgr;
            Configuration config;

            var solution = dte.Solution;

            if (dte.Solution.Projects.Count > 0)
            { 
                string solutionPath = solution.FullName;
            }

any alternative approach to generate build artifact for selected project?

Please refer the following code, which getting special project and build it.

please add reference: using Microsoft.Build.Construction;

using Microsoft.Build.Evaluation;

using Microsoft.Build.Framework;

string solutionPath = "yousolutionPath.sln";
                var solutionFile = SolutionFile.Parse(solutionPath);
                foreach (var item in solutionFile.ProjectsInOrder)
                {
                    Project project = ProjectCollection.GlobalProjectCollection.LoadProject(item.AbsolutePath);
                    project.SetGlobalProperty("Configuration", "Debug");
                    if (project.GetPropertyValue("RootNamespace") == "CppApp5")
                    {
                        project.Build("Build");
                    }
         }

As Jason said, you can get currentSoution via the following code.

 var componentModel = (IComponentModel)Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(SComponentModel));
 var workspace = componentModel.GetService<Microsoft.VisualStudio.LanguageServices.VisualStudioWorkspace>();
 Microsoft.CodeAnalysis.Solution sln = workspace.CurrentSolution;

6 Comments

Thanks for the replay, Can you explain how to initialize the "ServiceProvider" object inside the class library? Is there a way to do this via Workspace API and any examples on this?
If they're trying to use this in Visual Studio they shouldn't be using MSBuildWorkspace.
Is it a vsix project, can you get current visual studio DTE instance?
@Cole Wu-MSFT no its not a vsix project, Its a class lib.
My use case: User open the VS IDE -> Open a .cs file -> he select "Analyze" option which will be added from my extension -> then the extension should compile the project which contains user opened .cs file and place build artifacts it in a folder.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.