以编程方式强制使用计算的 MSBuild 属性值更新 Visual Studio 智能感知



>我正在尝试创建一个VSIX扩展,该扩展将下拉菜单添加到Visual Studio工具栏以控制自定义MSBuild属性的值。 该值确定要包含在项目中的 COMReference 版本,并且必须在不覆盖 .csproj 文件的情况下进行设置。我的 .csproj 文件的一部分:

<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>

我找到了 2 种可能的解决方案:

第一

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 使用实际值正确构建,但 Intellisense 无法识别来自 COMReferences 的任何内容 因此,智能感知功能不起作用,并且所有内容都以红色下划线显示。

第二:

将属性带到单独的文件中,并将其包含在主 csproj 中。通过 VSIX 修改 .props 文件后。

.csproj:

...
<Include Project="generatedMyProps.props"/>
<Coose> ... </Choose>
...

我的道具:

<Project ...>
<PropertyGroup>
<MyProperty Condition="'$(MyProperty )' == ''">MyValue1</MyProperty>
<DefineConstants>$(DefineConstants);$(MyProperty)</DefineConstants>
</PropertyGroup>
</Project>

这个解决方案效果很好。当我更改 MyValue1 时,在解决方案资源管理器中重新加载项目是不够的。有时重新启动Visual Studio甚至不够,您需要删除.suo文件。

如何让智能感知更新有关项目的信息,或者有人知道此问题的另一种解决方案?

我找到了解决方案。 此函数更新项目和智能感知:

VSLangProj80.VSProject2.Refresh();

全功能(刷新解决方案中的所有项目(:

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();
}           
}

最新更新