2017-08-15 73 views
1

我想创建一个VSIX扩展,向Visual Studio工具栏添加一个下拉菜单来控制自定义MSBuild属性的值。 该值确定要在项目中包含哪个版本的COMReference,并且必须设置该版本而不覆盖.csproj文件。我的.csproj文件的一部分:编程强制更新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> 

我发现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="generated\MyProps.props"/> 
<Coose> ... </Choose> 
... 

MyProps:

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

此解决方案苦头。当我更改MyValue1时,在解决方案资源管理器中重新加载项目是不够的。有时甚至不足以重新启动Visual Studio,并且需要删除.suo文件。

我该如何获得Intellisense更新关于该项目的信息,或者有人知道这个问题的另一种解决方案?

回答

1

我找到了解决办法。 此功能的更新项目和智能感知:

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