7

Given a string that represents a specific class/field/property (eg MyNameSpace.MyClass or System.String.Length), how can I programmatically cause Visual Studio to go to that class/field/property (ie, make Visual Studio do the same thing that would happen if I was to type in the reference in the code editor and then hit F12)?

Omer Raviv
  • 11,409
  • 5
  • 43
  • 82
  • 1
    F12/GotoDefn is a standard DevEnv command. Implementation is specific per package (C++, C#, VB.NET, F#, whatever). The only way to simulate this is to 1) select a text, a snippet, anything using the editor interface and 2) run the "Edit.GoToDefinition" command: http://stackoverflow.com/questions/20168945/how-do-i-use-dte-executecommandedit-gotodefinition-in-a-vs2010-c-macro – Simon Mourier Mar 12 '14 at 09:24
  • @SimonMourier But what if there's no text editor that contains the text of the thing I want to Go To? Is there any way to open an invisible text view, that is still bound to the same project, but without it having any effect on the project system or anything else, and will work in debug mode as well? – Omer Raviv Mar 14 '14 at 08:32
  • In the general case, that seems difficult. Are you looking to do this to support a specific package (C# files maybe?), or for all packages? Would it be an addin? an extension? – Simon Mourier Mar 14 '14 at 08:45
  • @SimonMourier Yes, I'm looking to target C# specifically, you can assume I only need to talk to the C# project system. I'm working on a VS Extension (a vspackage). – Omer Raviv Mar 14 '14 at 09:16

1 Answers1

11

You probably need to do the following.

  1. Get the global IVsObjectManager2 interface (implemented by the SVsObjectManager object)
  2. Call IVsObjectManager2.FindLibrary to get the C# library, and cast the result to IVsSimpleLibrary2.
  3. Call IVsSimpleLibrary2.GetList2 with the correct VSOBSEARCHCRITERIA2 in order to locate the symbol within the projects for your solution.

    1. If the resulting IVsSimpleObjectList2 has GetItemCount()==1, and CanGoToSource with VSOBJGOTOSRCTYPE.GS_DEFINITION returns pfOK==true, use the GoToSource method to jump to the source.

    2. Otherwise, rather than jumping to the source, simply display the possible options to the user. You will be able to use the IVsFindSymbol interface (implemented by the SVsObjectSearch object) to for this.

Omer Raviv
  • 11,409
  • 5
  • 43
  • 82
Sam Harwell
  • 97,721
  • 20
  • 209
  • 280
  • 1
    This works perfectly, thank you! In step 3.1, if `GetItemCount() == 1` and `CanGoToSource` returns false, is there any way to open the Object Browser window on that item, as an alternative to `GoToSource`? – Omer Raviv Mar 15 '14 at 09:35
  • @OmerRaviv How is it possible that, with the amount of parameters each of this calls has, and not a single piece of code, you could properly implement this? I need to do the same in VS2013 and I am totally lost. Can you please provide some code? Thanks. – JoanComasFdz Sep 04 '15 at 06:03
  • 3
    @JoanComasFdz I put my implementation of this in a Gist for you: https://gist.github.com/OmerRaviv/fc3ce6fbd5b6af501f01 Please note that this code won't work well in VS2015 because the new Roslyn language service is not 100% backwards compatible. In VS2015, a much more reliable and performant approach is to find the ISymbol of the thing you want to Go To, and then use ISymbol.Locations property to find out its source location. – Omer Raviv Sep 06 '15 at 08:56
  • @OmerRaviv Thanks for providing the code gist. But where does the `VisualStudioServices` come from in the snippet? – smwikipedia Oct 21 '17 at 13:58
  • I guess I found some hint: https://learn.microsoft.com/en-us/visualstudio/extensibility/how-to-get-a-service – smwikipedia Oct 21 '17 at 16:39