locked
Code model: Casting a property element to EnvDTE80::CodeProperty2 interface returns null... RRS feed

  • Question

  • Hello, 

    I'm working with Visual Studio 2008, accessing code model through EnvDTE and EnvDTE80 interfaces. 

    All code elements work fine with both libraries, except for the properties.

    CodeElement is cust nicely to CodeProperty, but not to CodeProperty2. 

    Did anyone have a similar problem? 

    Thanks in advance. 
    Sava.
    Tuesday, January 20, 2009 3:01 PM

Answers


  • Hi,

    Is very strange the problem, but I can find this error reported in the VS2005 beta2:

    https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=107634&wa=wsignin1.0


    I think that this error has not solved at present.


    I did a example and I am having the same error, I cann´t cast the CodeElement to CodeProperty2

    I post my example, you need to paste this code in a console solution.


    using System; 
     
    using EnvDTE; 
    using EnvDTE80; 
     
     
    namespace DTETest 
     
        class Program
        { 
            static void Main(string[] args) 
            { 
     
                DTEHelper.GetClassStructure(); 
     
                Console.ReadKey(); 
     
            } 
     
        } 
     
     
        public class Test<T> 
        { 
     
            private T _propiedadTest; 
     
            public T PropiedadTest 
            { 
                get { return _propiedadTest; } 
                set { _propiedadTest = value; } 
            } 
     
     
        } 
     
     
     
        public static class DTEHelper
        { 
            #region DTE - GetClassStructure 
     
            public static void GetClassStructure() 
            { 
     
                EnvDTE80.DTE2 _dte = (EnvDTE80.DTE2)System.Runtime.InteropServices.Marshal.GetActiveObject("VisualStudio.DTE.9.0"); 
     
                Solution2 _solution = _dte.Solution as Solution2;  
     
                Console.WriteLine(_solution.FullName); 
     
     
                foreach (Project project in _solution.Projects) 
                { 
                    Console.WriteLine("\t{0}", project.Name); 
     
                    foreach (ProjectItem item in project.ProjectItems) 
                    { 
     
                        Console.WriteLine("\t\t{0}", item.Name); 
     
                        FileCodeModel2 codeModel = item.FileCodeModel as FileCodeModel2; 
     
                        if (codeModel == null
                            continue
     
                        // 
                        // Process import for specific code file 
                        // 
                        GetClassMethods(codeModel); 
     
                    } 
                } 
            } 
     
     
            public static void GetClassMethods(FileCodeModel2 codeModel) 
            { 
     
                foreach (CodeElement2 itemCodeModel in codeModel.CodeElements) 
                { 
     
                    //Console.WriteLine("\t\t\t{0}", elementCodeModel.Kind); 
     
                    if (itemCodeModel.Kind == vsCMElement.vsCMElementNamespace) 
                    { 
     
                        CodeNamespace codeNamespace = (CodeNamespace)itemCodeModel; 
     
                        Console.WriteLine("\t\t\t{0}", codeNamespace.Name); 
                        #region Process - Class 
     
                        foreach (CodeElement2 itemNamespace in codeNamespace.Children) 
                        { 
     
                            if (itemNamespace.Kind == vsCMElement.vsCMElementClass) 
                            { 
                                CodeClass2 codeClass = (CodeClass2)itemNamespace; 
     
                                Console.WriteLine("\t\t\t\t{0}", codeClass.Name); 
                     
                                #region Process - property 
     
                                foreach (CodeElement2 itemClass in codeClass.Children) 
                                { 
     
                                    if (itemClass.Kind == vsCMElement.vsCMElementProperty) 
                                    { 
                                        CodeProperty codeProp = (CodeProperty)itemClass; 
     
                                        CodeProperty2 codeprop2 = itemClass as CodeProperty2; 
                                         
                                         
                                        Console.WriteLine("\t\t\t\t\t{0}", codeProp.Name); 
                                        Console.WriteLine("\t\t\t\t\t{0}", codeprop2 == null ? "null" : codeprop2.Name); 
                                    } 
                                } 
                                #endregion 
     
     
                            } 
                        } 
                        #endregion 
     
                    } 
     
                } 
            } 
            #endregion 
     
        } 
     
     
     


    As you can see I tried to use in all code the EnvDTE80, I thought that it can be the problem.

    I added a generic property, only with the CodeProperty2  is posible to answer if it is generic.




    Note: when run the console solution with this example, you must have only one VS open.
    If you have COM error you can continue.

    greetings



    Leandro Tuttini
    Tuesday, January 20, 2009 5:26 PM

All replies

  • Hi,

    If the CodeElement is a CodeProperty, try to cast it to a CodeProperty first and then to a CodeProperty2

    Pablo

    http://clariusconsulting.net/blogs/pga/
    Tuesday, January 20, 2009 3:35 PM
  • Thanks for an idea :) But unfortunately it does not solve the problem. 
    Tuesday, January 20, 2009 3:45 PM

  • Hi,

    Is very strange the problem, but I can find this error reported in the VS2005 beta2:

    https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=107634&wa=wsignin1.0


    I think that this error has not solved at present.


    I did a example and I am having the same error, I cann´t cast the CodeElement to CodeProperty2

    I post my example, you need to paste this code in a console solution.


    using System; 
     
    using EnvDTE; 
    using EnvDTE80; 
     
     
    namespace DTETest 
     
        class Program
        { 
            static void Main(string[] args) 
            { 
     
                DTEHelper.GetClassStructure(); 
     
                Console.ReadKey(); 
     
            } 
     
        } 
     
     
        public class Test<T> 
        { 
     
            private T _propiedadTest; 
     
            public T PropiedadTest 
            { 
                get { return _propiedadTest; } 
                set { _propiedadTest = value; } 
            } 
     
     
        } 
     
     
     
        public static class DTEHelper
        { 
            #region DTE - GetClassStructure 
     
            public static void GetClassStructure() 
            { 
     
                EnvDTE80.DTE2 _dte = (EnvDTE80.DTE2)System.Runtime.InteropServices.Marshal.GetActiveObject("VisualStudio.DTE.9.0"); 
     
                Solution2 _solution = _dte.Solution as Solution2;  
     
                Console.WriteLine(_solution.FullName); 
     
     
                foreach (Project project in _solution.Projects) 
                { 
                    Console.WriteLine("\t{0}", project.Name); 
     
                    foreach (ProjectItem item in project.ProjectItems) 
                    { 
     
                        Console.WriteLine("\t\t{0}", item.Name); 
     
                        FileCodeModel2 codeModel = item.FileCodeModel as FileCodeModel2; 
     
                        if (codeModel == null
                            continue
     
                        // 
                        // Process import for specific code file 
                        // 
                        GetClassMethods(codeModel); 
     
                    } 
                } 
            } 
     
     
            public static void GetClassMethods(FileCodeModel2 codeModel) 
            { 
     
                foreach (CodeElement2 itemCodeModel in codeModel.CodeElements) 
                { 
     
                    //Console.WriteLine("\t\t\t{0}", elementCodeModel.Kind); 
     
                    if (itemCodeModel.Kind == vsCMElement.vsCMElementNamespace) 
                    { 
     
                        CodeNamespace codeNamespace = (CodeNamespace)itemCodeModel; 
     
                        Console.WriteLine("\t\t\t{0}", codeNamespace.Name); 
                        #region Process - Class 
     
                        foreach (CodeElement2 itemNamespace in codeNamespace.Children) 
                        { 
     
                            if (itemNamespace.Kind == vsCMElement.vsCMElementClass) 
                            { 
                                CodeClass2 codeClass = (CodeClass2)itemNamespace; 
     
                                Console.WriteLine("\t\t\t\t{0}", codeClass.Name); 
                     
                                #region Process - property 
     
                                foreach (CodeElement2 itemClass in codeClass.Children) 
                                { 
     
                                    if (itemClass.Kind == vsCMElement.vsCMElementProperty) 
                                    { 
                                        CodeProperty codeProp = (CodeProperty)itemClass; 
     
                                        CodeProperty2 codeprop2 = itemClass as CodeProperty2; 
                                         
                                         
                                        Console.WriteLine("\t\t\t\t\t{0}", codeProp.Name); 
                                        Console.WriteLine("\t\t\t\t\t{0}", codeprop2 == null ? "null" : codeprop2.Name); 
                                    } 
                                } 
                                #endregion 
     
     
                            } 
                        } 
                        #endregion 
     
                    } 
     
                } 
            } 
            #endregion 
     
        } 
     
     
     


    As you can see I tried to use in all code the EnvDTE80, I thought that it can be the problem.

    I added a generic property, only with the CodeProperty2  is posible to answer if it is generic.




    Note: when run the console solution with this example, you must have only one VS open.
    If you have COM error you can continue.

    greetings



    Leandro Tuttini
    Tuesday, January 20, 2009 5:26 PM
  • This explains the situation. Thanks!
    Wednesday, January 21, 2009 10:25 AM