none
Why GetService(typeof(DTE)) return null?

    Question

  • In my package i neet access to automation object model for project items.

    I access it via DTE service:

     

    protected override void Initialize()

    {

      base.Initialize();

      DTE dte = (DTE)GetService(typeof(SDTE));

      DocumentEvents.DocumentSaved +=   DocumentEvents_DocumentSaved;

    }

     

    But _sometimes_ dte variable is null during package initialization.

    Why DTE service can not be found?

    Friday, August 17, 2007 10:01 AM

Answers

  • Oh, its simple enough.

    I need to perform some action (using CodeModel, accessible via DTE) after saving any C# file.

    GetService(typeof(DTE)) may be inaccessible during Initialize(), so i use RDT events:

     

        /// ... attrubutes

        public sealed class UniNetPackage : Package, IVsRunningDocTableEvents
        {
            protected override void Initialize()
            {
                try
                {
                    base.Initialize();

                   

                    // Get RDT service 

                    IVsRunningDocumentTable rdt = (IVsRunningDocumentTable)GetService(typeof(SVsRunningDocumentTable));

     

                    // Subscribe to RDT events               

                    uint pdwCookie;
                    RunningDocumentTable.AdviseRunningDocTableEvents(this, out pdwCookie);
                }
                catch (Exception e)
                {
                    string msg = String.Format(
                        "Initialize() exception:\r\n{0}\r\n{1}\r\nat\r\n{2}",
                        e.GetType(), e.Message, e.StackTrace);
                    LogError(msg);

                    throw;
                }
            }

     

            // ... another methods

     

            // Implementation of  IVsRunningDocTableEvents.OnAfterSave

            public int OnAfterSave(uint docCookie)
            {
                // Retrieve document info

                uint pgrfRDTFlags;
                uint pdwReadLocks;
                uint pdwEditLocks;
                string pbstrMkDocument;
                IVsHierarchy ppHier;
                uint pitemid;
                IntPtr ppunkDocData;
                RunningDocumentTable.GetDocumentInfo(
                    docCookie, out pgrfRDTFlags, out pdwReadLocks, out pdwEditLocks,
                    out pbstrMkDocument, out ppHier, out pitemid, out ppunkDocData);

     

                // Get automation-object Document and work with it

                ProjectItem prjItem = DTE.Solution.FindProjectItem(pbstrMkDocument);
                if (prjItem != null)
                    OnDocumentSaved(prjItem.Document);

                return VSConstants.S_OK;
            }

     

            // ... another methods

     

            // DocumentSaved handler, works with automation-based Document object

            private void OnDocumentSaved(Document doc)

            {

                 // Do actual work ....

            }
        }

     

    Monday, August 20, 2007 6:49 AM
  • ...and small forgotten piece of code, property DTE:

     

            internal DTE DTE
            {
                get
                {
                    DTE dte = (DTE)GetService(typeof(SDTE));
                    if (dte == null)
                    {
                        LogError("DTE service not found");
                        throw new InvalidOperationException("DTE service not found");
                    }

                    return dte;
                }
            }

    Monday, August 20, 2007 6:51 AM

All replies

  • Hi Igor,

    Have seen yet these old post?

    P.S. And it seems you made a mistype in 'SDTE', didn't you?

    Friday, August 17, 2007 11:38 AM
  • I solve my problem. The workaround is to use COM-services to listen events, and retrive DTE in handler, when DTE is accessible.

     

    SDTE is not mistake, it is mentioned in MSDN "Available services list" article, with many SVsXXXXX interfaces, used with GetService to receive IVsXXXX interfaces.

     

    On the other hand, GetService(typeof(DTE)) and GetService(typeof(SDTE)) seems to work identically Smile

     

    Saturday, August 18, 2007 2:52 PM
  • That is great!

     

    Could you please share a code snippet for obtaining the DTE in event handler using "COM-services" way you mentioned?

     

    Thanks,

    Monday, August 20, 2007 1:44 AM
  • Oh, its simple enough.

    I need to perform some action (using CodeModel, accessible via DTE) after saving any C# file.

    GetService(typeof(DTE)) may be inaccessible during Initialize(), so i use RDT events:

     

        /// ... attrubutes

        public sealed class UniNetPackage : Package, IVsRunningDocTableEvents
        {
            protected override void Initialize()
            {
                try
                {
                    base.Initialize();

                   

                    // Get RDT service 

                    IVsRunningDocumentTable rdt = (IVsRunningDocumentTable)GetService(typeof(SVsRunningDocumentTable));

     

                    // Subscribe to RDT events               

                    uint pdwCookie;
                    RunningDocumentTable.AdviseRunningDocTableEvents(this, out pdwCookie);
                }
                catch (Exception e)
                {
                    string msg = String.Format(
                        "Initialize() exception:\r\n{0}\r\n{1}\r\nat\r\n{2}",
                        e.GetType(), e.Message, e.StackTrace);
                    LogError(msg);

                    throw;
                }
            }

     

            // ... another methods

     

            // Implementation of  IVsRunningDocTableEvents.OnAfterSave

            public int OnAfterSave(uint docCookie)
            {
                // Retrieve document info

                uint pgrfRDTFlags;
                uint pdwReadLocks;
                uint pdwEditLocks;
                string pbstrMkDocument;
                IVsHierarchy ppHier;
                uint pitemid;
                IntPtr ppunkDocData;
                RunningDocumentTable.GetDocumentInfo(
                    docCookie, out pgrfRDTFlags, out pdwReadLocks, out pdwEditLocks,
                    out pbstrMkDocument, out ppHier, out pitemid, out ppunkDocData);

     

                // Get automation-object Document and work with it

                ProjectItem prjItem = DTE.Solution.FindProjectItem(pbstrMkDocument);
                if (prjItem != null)
                    OnDocumentSaved(prjItem.Document);

                return VSConstants.S_OK;
            }

     

            // ... another methods

     

            // DocumentSaved handler, works with automation-based Document object

            private void OnDocumentSaved(Document doc)

            {

                 // Do actual work ....

            }
        }

     

    Monday, August 20, 2007 6:49 AM
  • ...and small forgotten piece of code, property DTE:

     

            internal DTE DTE
            {
                get
                {
                    DTE dte = (DTE)GetService(typeof(SDTE));
                    if (dte == null)
                    {
                        LogError("DTE service not found");
                        throw new InvalidOperationException("DTE service not found");
                    }

                    return dte;
                }
            }

    Monday, August 20, 2007 6:51 AM