4

I'm developing an extension for VS2015 and i need to get the project folder of the opened solution. And then find the bin folder to get the output DLL. All this because i need to instantiate a class from the output DLL using reflection.

I tried to get some information from msdn but it's difficult to me understand. Is there a way to do this?

Thanks in advance

Matze
  • 5,100
  • 6
  • 46
  • 69
  • The solution itself does not have an output folder, but the solution can contain multiple projects - and each project has it´s own output directory (which depends on the selected solution configuration). – Matze Oct 09 '15 at 06:17

1 Answers1

2

You could try something like this...

Find the project file of interest (maybe the startup project), or let the user select it. The project output directory is stored within it´s project file, so one should use MSBuild to read that information, or the better: let MSBuild evaluate the project assembly´s target path property. What you need would be the absolute path of the project file, or an EnvDTE.Project reference.

The absolute path to an output assembly can be obtained by evaluating the TargetPath property. You need to reference the Microsoft.Build.dll assembly, create a new project-collection and load the project by creating a new instance of the Microsoft.Build.Evaluation.Project class. This will allow you to query defined properties from the project and their evaluated values...

using Microsoft.Build.Evaluation;

...

public static string GetTargetPathFrom(EnvDTE.VsProject project)
{
    const string PropertyName = "TargetPath";
    return GetPropertyValueFrom(project.FileName, PropertyName);
}

public static string GetPropertyValueFrom(string projectFile, string propertyName)
{
    using (var projectCollection = new ProjectCollection())
    {
        var p = new Project(
            projectFile, 
            null, 
            null, 
            projectCollection, 
            ProjectLoadSettings.Default);

        return p.Properties
            .Where(x => x.Name == propertyName)
            .Select(x => x.EvaluatedValue)
            .SingleOrDefault();
        }
    }
}

The sample provided above will use the default project build configuration; I haven´t tried it, but it may work to change the Platform and Configuration properties by passing global properties to the Project ctor. You could try this...

...

var globalProperties = new Dictionary<string, string>()
    {
        { "Configuration", "Debug" }, 
        { "Platform", "AnyCPU" }
    };

var p = new Project(
    projectFile, 
    globalProperties, 
    null, 
    projectCollection,
    ProjectLoadSettings.Default);

...
Matze
  • 5,100
  • 6
  • 46
  • 69
  • 1
    Thanks for the help, i just have to change "var p = new Project"( to "new Microsoft.Build.Evaluation.Project" because of references conflicts. – Renato Ramos Nascimento Oct 09 '15 at 12:44
  • 'Properties' does not contain a definition for 'Where' and no accessible extension method 'Where' accepting a first argument of type 'Properties' could be found – Steve Andrews May 16 '20 at 16:41