Getting an existing method from VSTA, then updating it

Latest post 07-09-2007 9:56 AM by Gary. 9 replies.
  • 06-14-2007 12:28 PM

    Getting an existing method from VSTA, then updating it

    The ShapeApp examples demonstrate adding methods to the VSTA project, by calling 'IVstaProjectHostItem.AddMethod'. This lets you pass a method, defined as a CodeDOM tree, to VSTA and add it to the currently loaded project. We are OK with this, and have incorporated it into our prototype application.

    However, we also need to be able to get code from the VSTA project, update it, and then pass it back to VSTA. Ideally, we would like to obtain an entire method as a CodeDOM tree. Having done this, we would change the method (i.e. add new statements, remove existing statements, etc), and then pass the updated method back to the VSTA project. The IVstaProjectHostItem interface does not seem to allow this.

    I hope the above is clear. Basically, our problem is that the IVstaProjectHostItem interface allows you to add a new method, but we also need to:

    1 - get an existing method (preferably as a CodeDOM tree);

    2 - having changed the method as required, update it in VSTA.

    Am I missing something obvious? Is there a way of obtaining an existing method, and then updating (i.e. replacing) it?

    At present, we can add a new method to a VSTA project, but we have no way of finding out anything at all about the methods, properties, etc which are already in the project.

    Filed under:
  • 06-14-2007 6:08 PM In reply to

    • Melody
    • Top 10 Contributor
    • Joined on 04-26-2007
    • Syracuse, NY
    • Posts 244

    Re: Getting an existing method from VSTA, then updating it

    John,

    The IVstaProjectHostItem will not allow you to get and update or replace a method from the VSTA project.  You can get the paths to the blueprint and the code files, but IVstaProjectHostItem does not include any way to alter or remove a method from the VSTA project.  I will look into other ways of doing this and get back to you.

    Here’s a breakdown of IVstaProjectHostItem:

    Represents the host item in the project.

    The following tables list the members exposed by the IVstaProjectHostItem type.

    Public Properties

     

    Name

    Description

    BlueprintFilePath

    Gets the path to the blueprint for the ProjectHostItem

    CodeFilePath

    Gets the path to the code file for the ProjectHostItem

    FileNamespace

    Gets the namespace contained in the host item code file. 

    GenerateCodeBehind

    Gets or sets a value that indicates whether to create an empty code-behind file for the host item. 

    HostItemClass

    Gets the name of the host item class without the default namespace. 

    Namespace

    Gets the namespace of the host item. 

    Top

    Public Methods

     

    Name

    Description

    AddEventHandler

    Adds an event handler to the host item's code file.  

    AddMethod

    Adds a method to the host item's code file.  

    IsEventHandled

    Indicates whether the specified event is handled in the user code file.  


     

  • 06-18-2007 12:06 PM In reply to

    • Melody
    • Top 10 Contributor
    • Joined on 04-26-2007
    • Syracuse, NY
    • Posts 244

    Re: Getting an existing method from VSTA, then updating it

    John,

       It is possible to get a method as a CodeDom object, update it and use the updated version; however, you may not use IVstaProjectHostItem to do this.  I checked out some MSDN forumns related to this and found a couple different options.  Here are links to the posts for you to check out directly.  I hope this helps!

    -Melody

     

    http://forums.microsoft.com/msdn/ShowPost.aspx?PostID=24860&SiteID=1

       (check out the second to last post)

     

    http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=229146&SiteID=1

     

    msdn info on CodeDom and CodeDom.Compiler

    http://msdn2.microsoft.com/en-us/library/system.codedom.aspx

    http://msdn2.microsoft.com/en-us/library/system.codedom.compiler.aspx

  • 06-22-2007 5:00 AM In reply to

    Re: Getting an existing method from VSTA, then updating it

    Melody,

    I tried out the code in the second to last post on the first thread you indicated, which seems as though it should do what I want - but amongst other things, it requires an IDesignerHost interface. I have tried to get one from VSTA, but without success. Do you know how to do this?

    Thanks

     

  • 06-22-2007 11:28 AM In reply to

    • Melody
    • Top 10 Contributor
    • Joined on 04-26-2007
    • Syracuse, NY
    • Posts 244

    Re: Getting an existing method from VSTA, then updating it

    John,

    Are you using the full namespace for the declaration (System.ComponentModel.Design.IDesignerHost)? I am able to do this without adding any references or using/import statements. 

    If using the full namespace doesn’t work (which I hope it does!) I did find examples of how to use this in both the SDK and some on-line articles.  For the SDK check out the section on IDesignerHost Interface, there are examples in VB, C# and C++ here.  A good on-line example, which illustrates how to add a control to a Windows Form from a VS add-in, is http://www.mztools.com/Articles/2006/MZ016.htm. 

    I hope this helps.  If you are still stuck please send me a sample and I’ll see what I can do.

    Thanks,

                    -Melody

  • 06-25-2007 9:21 AM In reply to

    Re: Getting an existing method from VSTA, then updating it

    Melody,

    I think that I didn't explain my problem clearly enough - what I meant was that I can't figure out how to get an IDesignerHost object from VSTA. Sorry for the misunderstanding.

    Do you know how to do this - i.e. how to get an IDesignerHost object from VSTA?

    Thanks very much for your help.

     

  • 06-29-2007 2:59 PM In reply to

    • Gary
    • Top 10 Contributor
    • Joined on 07-13-2006
    • Posts 307

    Re: Getting an existing method from VSTA, then updating it

    John,

    I haven't determined how to use CodeDOM for editing an existing Class and its methods.  As I see it CodeDOM is a tool that only generates code (and compiles).  CodeDOM has no way to auto-populate its graph from an existing CodeModel or 'suck in' a source file to create its graph -- again, there is no mapping from the DTE's CodeModel to a CodeDom graph. 

    So the easiest way that I can see is to find your method, then remove it and replace it with the changes you require.  Below, is the code to remove a method using CodeClass.  Then you can add/insert/replace it using CodeModel (which is not language agnostic) or you can use CodeDOM to create the new method and add the new method using IVstaProjectHostItem.AddMethod(CodeMemberMethod method) as demonstrated in the VSTA SDK macro recorder samples 

    Checkout EnvDTE80's; CodeClass2:

    Specifically: CodeClass2.RemoveMember () and AddFunction()

    When the macro recording is finished in the AdvancedCSharpShapeApp sample, SaveMacro() gets the Addin Class and uses a CodeDom.CodeMemberMethod to add a method:

    hostAdapter.ProjectHostItems[0].AddMethod(method);

    but prior to this, the correct CodeClass is determined by name lookup

    sampleEnvDTE.CodeClass hostItemClass = FindClass(hostItemClassName, hostItemProjectItem.FileCodeModel.CodeElements);

    And this is a good context to illustrate the use of AddFunction and RemoveMember:

    A CodeClass instance, like hostItemClass in this example, can be used to add and remove class methods as follows:

    //Add

    elt = (EnvDTE.CodeElement)(hostItemClass .AddFunction(defaultName,

    EnvDTE.vsCMFunction.vsCMFunctionFunction,

    EnvDTE.vsCMTypeRef.vsCMTypeRefInt, -1,

    EnvDTE.vsCMAccess.vsCMAccessDefault, null));

    //remove

    hostItemClass .RemoveMember(elt);

    Here's a blog that uses EnvDTE codemodel more extensively:

    http://mikehadlow.blogspot.com/2006/09/how-to-examine-code-and-write-class.html

  • 07-02-2007 8:41 AM In reply to

    Re: Getting an existing method from VSTA, then updating it

    Gary,

    When you say that CodeDOM cannot 'suck in' a source file - do you mean that it cannot parse source code? I have tried to use the CreateParser and Parse methods on a CSharpCodeProvider, without success so far (CreateParser returned null, and Parse threw a NotImplementedException). Is there no way of getting these methods to work?

    Thanks for your help.

    John

     

  • 07-06-2007 8:25 AM In reply to

    • Melody
    • Top 10 Contributor
    • Joined on 04-26-2007
    • Syracuse, NY
    • Posts 244

    Re: Getting an existing method from VSTA, then updating it

    John,

         According to the SDK, the NotImplementedException for the Parse method is thrown if the Parse and CreateGenerator methods are not overridden in the derived class, or if the Parse method is overriden and the corresponding method of the base class is called.  The CreateParser will always return null from the base implementation.  Check out your inheritence and overrides to see if this is the issue. 

     

    -Melody

  • 07-09-2007 9:56 AM In reply to

    • Gary
    • Top 10 Contributor
    • Joined on 07-13-2006
    • Posts 307

    Re: Getting an existing method from VSTA, then updating it

    Hi John,

    >>When you say that CodeDOM cannot 'suck in' a source file - do you mean that it cannot parse source >>code?

    I meant to say that CodeDOM is really a one-way street.  It's not useful for editing source code.  CodeDOM cannot 'consume' source code without you implementing a source code parser and creating a CodeDOM graph.  This is probably much too complex for your purposes of 'getting an existing method and updating it'.  That is why we recommended and demonstrated the use of 'CodeModel' which should serve your purposes well enough.

     

     

Page 1 of 1 (10 items) | RSS
Copyright Summit Software Company, 2008. All rights reserved.