I'm trying to create a VSIX extension that adds a drop-down menu to the Visual Studio toolbar to control the value of the custom MSBuild property. The value determines which version of COMReference to include in the project and it must be set without overwriting the .csproj file. Part of my .csproj file:
<Project ... >
<Choose>
<When Condition="'$(MyProperty)'=='MyValue1'">
<ItemGroup>
<COMReference Include="ComLib">
Version_1
</COMReference>
</ItemGroup>
</When>
<When Condition="'$(MyProperty)'=='MyValue2'">
<ItemGroup>
<COMReference Include="ComLib">
Version_2
</COMReference>
</ItemGroup>
</When>
</Choose>
</Project>
I found 2 possible solutions:
First
public static void SetGlobalBuildProperty( string property, string value )
{
var projects = Microsoft.Build.Evaluation.ProjectCollection
.GlobalProjectCollection
.LoadedProjects;
foreach ( Microsoft.Build.Evaluation.Project project in projects )
{
project.SetGlobalProperty( property, value );
project.MarkDirty();
project.ReevaluateIfNecessary();
}
}
Broject builds correctly with actual value, but Intellisense does not recognize anything from COMReferences so the Intellisense functions do not work and everything is underlined in red.
Second:
Bring the property to a separate file and include it in the main csproj. After modify .props file via VSIX.
.csproj:
...
<Include Project="generated\MyProps.props"/>
<Coose> ... </Choose>
...
MyProps:
<Project ...>
<PropertyGroup>
<MyProperty Condition="'$(MyProperty )' == ''">MyValue1</MyProperty>
<DefineConstants>$(DefineConstants);$(MyProperty)</DefineConstants>
</PropertyGroup>
</Project>
This solution works terribly. When I change MyValue1, it is not enough to reload the project in Solution Explorer. Sometimes it's not even enough to restart Visual Studio, and you need to delete the .suo file.
How can I get Intellisense to update the information about the project or maybe someone knows another solution to this problem?
I found solution. This function updates project and Intellisense:
VSLangProj80.VSProject2.Refresh();
Full function (refresh all projects in solution):
public static void SetGlobalBuildProperty( IServiceProvider package, string property, string value )
{
var projects = Microsoft.Build.Evaluation.ProjectCollection
.GlobalProjectCollection
.LoadedProjects;
foreach ( var project in projects )
{
project.SetGlobalProperty( property, value );
project.MarkDirty();
project.ReevaluateIfNecessary();
}
var dte = package.GetService( typeof( DTE ) ) as DTE2;
var solution = dte.Solution as Solution2;
var dteProjects = GetSolutionProjects( solution ) //Get all solution projects.
foreach( var project in dteProjects )
{
var vsProject = project.Object as VSProject2;
vsproject.Refresh();
}
}