Я использую 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. Элемент https://msdn.microsoft.com/en-US/library/microsoft.visualstudio.vcprojectengine.ivccollection.item(v=vs.140).aspx в команду Visual Commander, и получил тот же результат.
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 ”и получила такой же плохой результат.)
Благодаря Сергею Власову, автору 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)
Теперь все в порядке с этим макросом.
Других решений пока нет …