代码之家  ›  专栏  ›  技术社区  ›  R. Savelyev

以编程方式强制更新具有已评估MSBuild属性值的Visual Studio Intellisense

  •  3
  • R. Savelyev  · 技术社区  · 7 年前

    我正在尝试创建一个VSIX扩展,该扩展将下拉菜单添加到Visual Studio工具栏,以控制自定义MSBuild属性的值。

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

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

    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公司:

    ...
    <Include Project="generated\MyProps.props"/>
    <Coose> ... </Choose>
    ...
    

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

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

    1 回复  |  直到 7 年前
        1
  •  2
  •   R. Savelyev    7 年前

    我找到了解决办法。 此函数用于更新project和Intellisense:

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