Не удается найти VCCLCompilerTool в макросе VS2015 (с использованием Visual Commander)

Я использую Visual Commander (из https://vlasovstudio.com/visual-commander/) для переноса некоторых макросов для управления проектами C++ с VS2010 до VS2015. Кажется, что все работает хорошо (я могу получить доступ к решениям, создать VCProjects, пройтись по Конфигурациям и т. Д.), Но у меня есть одна проблема - вызов, который работал в VS2010:

cfg.Tools("VCCLCompilerTool")

... завершается сбоем в VS2015 с "System.MissingMemberException: не найден элемент по умолчанию для типа" VCCollectionShim "." ошибка, означающая, что в коллекции нет элемента "VCCLCompilerTool".

Кто-нибудь знает, как это исправить? Или другой способ получить доступ к настройкам компилятора C++ для конфигурации? (Кроме ручного анализа XML-файла vcxproj.)

Если я распечатываю значение ToString() каждого элемента в cfg.Tools, я просто вижу "прокладки", такие как "Microsoft.VisualStudio.Project.VisualC.VCProjectEngine.VCCLCompilerToolShim".

Если я делаю то же самое в реальном макросе VS2010 (который работает), каждый элемент отображается как "System.__ComObject".

Поиск в Интернете показывает, что ошибка "shim" означает, что код обращается к неверной версии сборок VCProjectEngine или VCProject. У меня есть VS2005 и VS2010, установленные для использования в других проектах, но я временно переименовал все места, где старые версии этих библиотек DLL живут и до сих пор сталкиваются с той же проблемой. Может быть, он все еще получает его откуда-то еще, как GAC?

Я попытался вставить образец из документации по методу IVCCollection.Item по адресу https://msdn.microsoft.com/en-US/library/microsoft.visualstudio.vcprojectengine.ivccollection.item(v=vs.140).aspx в визуальный файл. Командир командовал и получил такой же результат.

Imports EnvDTE
Imports EnvDTE80
Imports Microsoft.VisualBasic

Imports System

Imports System.Diagnostics
Imports Microsoft.VisualStudio.VCProjectEngine
Imports System.Text

Public Class C
    Implements VisualCommanderExt.ICommand

    Sub Run(DTE As EnvDTE80.DTE2, package As Microsoft.VisualStudio.Shell.Package) Implements VisualCommanderExt.ICommand.Run
        EnablePREfastExample(DTE)
    End Sub

Sub EnablePREfastExample(ByVal dte As DTE2)
    Dim prj As VCProject
    Dim cfgs, tools As IVCCollection
    Dim cfg As VCConfiguration
    Dim tool As VCCLCompilerTool
    Dim sb As New StringBuilder

    prj = CType(dte.Solution.Projects.Item(1).Object, _
      Microsoft.VisualStudio.VCProjectEngine.VCProject)

    cfgs = CType(prj.Configurations, _
      Microsoft.VisualStudio.VCProjectEngine.IVCCollection)

    cfg = CType(cfgs.Item(1), _
      Microsoft.VisualStudio.VCProjectEngine.VCConfiguration)

' This fails
    tool = CType(cfg.Tools("VCCLCompilerTool"), _
      Microsoft.VisualStudio.VCProjectEngine.VCCLCompilerTool)


    sb.Length = 0
    sb.Append("Current project PREfast setting: " _
      & tool.EnablePREfast & Environment.NewLine)
    sb.Append("Flag: " & tool.AdditionalOptions)
    MsgBox(sb.ToString)

End Sub
End Class

Я установил значение в диалоговом окне "Ссылки..." в Visual Commander на "Microsoft.VisualStudio.VCProjectEngine". (Я также попытался полностью указать имя пути, например "C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\PublicAssemblies\Microsoft.VisualStudio.VCProjectEngine.dll", или полное имя GAC, например "Microsoft.VisualStudio"..VCProjectEngine, версия =14.0.0.0, культура = нейтральная, PublicKeyToken=b03f5f7f11d50a3a”и получила такой же плохой результат.)

1 ответ

Благодаря Сергею Власову, автору Visual Commander, я нашел ответ. Он указал, что версия примера кода на C# работала в VS2015. Код C# и VB немного отличается в рассматриваемой строке. Код C#:

tool = 
  (Microsoft.VisualStudio.VCProjectEngine.VCCLCompilerTool)
  tools.Item("VCCLCompilerTool");

в то время как код VB:

tool = CType(cfg.Tools("VCCLCompilerTool"), _
  Microsoft.VisualStudio.VCProjectEngine.VCCLCompilerTool)

Этот VB отлично работает в VS2010, но, похоже, в VS2015 коллекция инструментов больше не может индексироваться по имени по умолчанию. Поэтому мне просто нужно было добавить ".Item", который изменил код VB на это:

tool = CType(cfg.Tools.Item("VCCLCompilerTool"), _
  Microsoft.VisualStudio.VCProjectEngine.VCCLCompilerTool)

Теперь все в порядке с этим макросом.

Другие вопросы по тегам