简体   繁体   中英

Cannot find VCCLCompilerTool in VS2015 macro (using Visual Commander)

I am using Visual Commander (from https://vlasovstudio.com/visual-commander/ ) to port some macros for manipulating C++ projects from VS2010 to VS2015. Things seem to work OK (I can access solutions, create VCProjects, loop through Configurations, etc.), but I am having one problem - the call which worked in VS2010:

cfg.Tools("VCCLCompilerTool")

...fails in VS2015, with a "System.MissingMemberException: No default member found for type 'VCCollectionShim'." error, suggesting that the collection doesn't have a "VCCLCompilerTool" item.

Does anyone know how to fix this? Or another way to get access to the C++ compiler settings for a configuration? (Other than manually parsing the vcxproj XML file.)

If I print out the ToString() value of each item in cfg.Tools, I just see 'shims' such as 'Microsoft.VisualStudio.Project.VisualC.VCProjectEngine.VCCLCompilerToolShim'.

If I do the same in a real VS2010 macro (which works), every item shows as 'System.__ComObject'.

Searching on the internet suggests that a 'shim' error means that the code is accessing the wrong version of the VCProjectEngine or VCProject assemblies. I do have VS2005 and VS2010 installed for use in other projects, but I've temporarily renamed every place where old versions of these DLLs live and still get the same problem. Maybe it's still getting it from somewhere else, like the GAC?

I tried inserting the sample from the IVCCollection.Item Method documentation at https://msdn.microsoft.com/en-US/library/microsoft.visualstudio.vcprojectengine.ivccollection.item(v=vs.140).aspx into a Visual Commander command, and got the same result.

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

I set the value in the References… dialog in Visual Commander to "Microsoft.VisualStudio.VCProjectEngine". (I also tried fully specifying the path name like "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\Common7\\IDE\\PublicAssemblies\\Microsoft.VisualStudio.VCProjectEngine.dll", or a full GAC name like “Microsoft.VisualStudio.VCProjectEngine, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a” and got the same bad result.)

Thanks to Sergey Vlasov, author of Visual Commander, I found the answer. He pointed out that the C# version of the sample code worked in VS2015. The C# and VB code are slightly different in the line in question. The C# code is:

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

while the VB code is:

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

This VB works fine in VS2010, but it looks like in VS2015, the Tools collection can no longer be indexed by name by default. So I just needed to add ".Item", which changed the VB code to this:

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

Now everything's fine with this macro.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM