2010-09-25 11 views
8

Gói Visual Studio của tôi yêu cầu sử dụng biến EnvDTE.DTE, nhưng nó luôn được trả về là rỗng. Sau khi đọc trên nhiều hacks, tất cả chúng đều sử dụng phương thức OnShellPropertyChange() (IVsShellPropertyEvents), nhưng đôi khi nó không bao giờ cháy - như thể phần mở rộng của tôi chưa bao giờ kết thúc tải.VSIX: Nhận đối tượng DTE

Tôi đang sử dụng VS2010 và kiểm tra chống lại cả VSSPROPID_Zombie và ShellInitialized - không hoạt động. ? :(

Bất kỳ ý tưởng Đây là mã Tôi đang sử dụng:

public int OnShellPropertyChange(int propid, object var) { 
      if (propid == -9053 || (int) __VSSPROPID.VSSPROPID_Zombie == propid) { // -9053 = ShellInit 
       try { 
        if ((bool) var == false) { 
         Dte = GetService(typeof (SDTE)) as DTE; 
         Flow.Dte = Dte; 

         var shellService = GetService(typeof (SVsShell)) as IVsShell; 

         if (shellService != null) 
          ErrorHandler.ThrowOnFailure(shellService.UnadviseShellPropertyChanges(_cookie)); 

         _cookie = 0; 
        } 
       } catch { 

       } 
      } 

      return VSConstants.S_OK; 
     } 

EDIT: Theo thực nghiệm sơ thẩm, nó hoạt động một cách hoàn hảo và mất khoảng 5 giây để khởi Tuy nhiên, khi triển khai như VSIX - nó. chỉ đơn giản là không cháy.

Trả lời

6

tôi nhìn thấy một vài vấn đề ở đây:

  • Bạn thực sự nên sử dụng __VSSPROPID4.VSSPROPID_ShellInitialized (quy định tại Microsoft.VisualStudio.Shell.Interop .10.0) thay vì -9083 cho dễ đọc
  • Bạn nên kiểm tra ShellInitialized được đặt thành true (mặc dù kiểm tra xem có lỗi cho Zombie là sai không)
  • Hãy nhớ rằng ShellInitialized sẽ thay đổi thành true sau khi ... khi khởi động VS. Kiểm tra cho nó là cách tiếp cận đúng nếu gói của bạn được đăng ký để tự động tải khi khởi động (có thể xảy ra trước khi VS hoàn toàn sẵn sàng để đi). Tuy nhiên, hầu hết các gói phải không tự động tải khi khởi động, nhưng thay vì tải theo yêu cầu từ một số hành động của người dùng yêu cầu mã gói của bạn. Sau đó bạn có thể kiểm tra dịch vụ DTE trong phương thức khởi tạo lớp gói của bạn.
+0

VSSPROPID4 đã cho tôi một số vấn đề mơ hồ, đó là lý do tại sao tôi đã đi với số nguyên cho bây giờ. Tôi sẽ thay đổi điều kiện và xem nó có hoạt động không - cảm ơn! –

5

Nếu bạn có một thành phần MEF cách dễ nhất để có được một đối tượng DTE như sau

Đầu tiên thêm một tham chiếu đến Microsoft.VisualStudio.Shell.Immutable.10. sau đó, thêm một Nhập MEF cho SVsServiceProvider. đối tượng có một phương pháp GetService mà có thể được truy vấn cho DTE

[ImportingConstructor] 
public MyComponent(SVsServiceProvider serviceProvider) { 
    _DTE dte = (_DTE)serviceProvider.GetService(typeof(_DTE)); 
} 
+0

Tôi chưa có thành phần MEF. Bất kỳ ý tưởng nào về lý do tại sao tài sản không bao giờ thay đổi? Đó là một dự án VS VMSDK. –

3

Tôi biết bạn chọn một câu trả lời đã được nhưng bạn đã xác định rằng bạn didnt muốn sử dụng MEF vì vậy tôi nghĩ tôi sẽ gửi một sự thay thế chỉ vì lợi ích của sự hoàn chỉnh ....; p

 

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Runtime.InteropServices; 
using EnvDTE; 
using EnvDTE80; 

namespace DTETesting 
{ 
    class Program 
    { 
     const string ACTIVE_OBJECT = "VisualStudio.DTE.10.0"; 
     static void Main(string[] args) 
     { 
      EnvDTE80.DTE2 MyDte; 
      MyDte = (EnvDTE80.DTE2)System.Runtime.InteropServices.Marshal.GetActiveObject(ACTIVE_OBJECT); 
      Console.WriteLine("The Edition is "+MyDte.Edition); 
      Console.ReadLine(); 
     } 
    } 
} 
 
+0

Gọn gàng. Thanks :) –

+0

tìm thấy điều này quá, http://msdn.microsoft.com/en-us/library/68shb4dw%28v=VS.100%29.aspx – Terrance

+0

Hãy coi chừng: nếu bạn đang chạy nhiều hơn một trường hợp của Visual Studio , điều này sẽ giúp bạn có được một trong số họ, nhưng không nhất thiết phải là một trong những bạn đang chạy. – RichieHindle

23

Hãy thử lệnh sau:

dte = Package.GetGlobalService(typeof(DTE)) as DTE2; 
+2

Điều này làm việc cho tôi, chỉ cần thêm một tham chiếu đến Microsoft.VisualStudio.Shell.dll trong dự án. –

+0

Tính năng này cũng phù hợp với tôi. Tôi đang sử dụng trong mã phía sau giao diện người dùng XAML. –