2010-01-13 25 views
21

Tôi có một số công cụ thực hiện cập nhật trên các giải pháp .NET, nhưng chúng cần phải biết thư mục chứa giải pháp.Lập trình thư mục giải pháp Visual Studio IDE hiện tại từ addins

Tôi đã thêm những công cụ này làm Công cụ bên ngoài, nơi chúng xuất hiện trong trình đơn Công cụ IDE và cung cấp $(SolutionDir) làm đối số. Điều này hoạt động tốt. Tuy nhiên, tôi muốn các công cụ này dễ truy cập hơn trong IDE cho người dùng thông qua trình đơn cấp cao nhất tùy chỉnh (mà tôi đã tạo dự án gói tích hợp Visual Studio) và thông qua menu ngữ cảnh trên các nút giải pháp (trong đó Tôi đã tạo một dự án bổ trợ Visual Studio). Tôi đang tìm một cách để có được thư mục giải pháp hiện tại thông qua các ngữ cảnh này.

tôi đã cố gắng nhận được thông tin giải pháp từ đối tượng VisualStudio.DTE:

EnvDTE.DTE dte = (EnvDTE.DTE)System.Runtime.InteropServices.Marshal.GetActiveObject("VisualStudio.DTE"); 
string solutionDir = System.IO.Path.GetDirectoryName(dte.Solution.FullName); 

Nhưng, điều này sẽ trả về thư mục giải pháp cho in thêm, không phải là giải pháp hiện tại.

tôi đã cố gắng lặp lại $(SolutionDir) và đọc nó trở lại:

System.Diagnostics.ProcessStartInfo procStartInfo = new System.Diagnostics.ProcessStartInfo("cmd", "echo $(SolutionDir)"); 

// The following commands are needed to redirect the standard output. 
// This means that it will be redirected to the Process.StandardOutput StreamReader. 
procStartInfo.RedirectStandardOutput = true; 
procStartInfo.UseShellExecute = false; 
// Do not create the black window. 
procStartInfo.CreateNoWindow = true; 
// Now we create a process, assign its ProcessStartInfo and start it 
System.Diagnostics.Process proc = new System.Diagnostics.Process(); 
proc.StartInfo = procStartInfo; 
proc.Start(); 
// Get the output into a string 
string result = proc.StandardOutput.ReadToEnd(); 

Nhưng, này trả lại thư mục cho IDE, không phải là giải pháp hiện tại.

Tôi không thấy bất kỳ thông tin liên quan nào trong nút giải pháp CommandBar.

Ngoài ra, nếu có cách để truy cập theo chương trình các công cụ bên ngoài Visual Studio đã xác định và khởi chạy chúng (sử dụng các đối số macro đã được xác định), điều đó sẽ hoạt động.

Giải pháp là gì?

+0

2+ một lần nữa dường như tôi đang theo dõi bạn ở đây Với sự điên rồ DTE này lol – Terrance

Trả lời

18

EnvDTE.DTE DTE = (EnvDTE.DTE) System.Runtime.InteropServices.Marshal.GetActiveObject ("VisualStudio.DTE"); giải pháp chuỗiDir = System.IO.Path.GetDirectoryName (dte.Solution.FullName);

Tuy nhiên, điều này trả về giải pháp thư mục cho phần bổ trợ, không phải là giải pháp hiện tại .

Cách tiếp cận của bạn để nhận thư mục là tốt. Có gì sai là cách bạn nhận được đối tượng VisualStudio.DTE. Mã này được gọi ở đâu? Tôi cho rằng nó nằm trong add-in của bạn. Bạn có thực hiện (gỡ lỗi) bổ trợ của bạn trong Visual Studio mở ra một thể hiện của Visual Studio, nơi bạn mở giải pháp của bạn? Vì vậy, bạn có hai trường hợp của Visual Studio.

GetActiveObject("VisualStudio.DTE") có phiên bản Visual Studio ngẫu nhiên. Trong trường hợp của bạn, rõ ràng là Visual Studio với một dự án bổ trợ kể từ khi bạn nhận được đường dẫn đến bổ trợ của bạn. Đó là để giải thích những gì sẽ là lý do của vấn đề của bạn.

Cách chính xác để nhận DTE rất đơn giản. Trong thực tế, bổ trợ của bạn đã có tham chiếu đến DTE mà nó chạy (tức là, trong đó giải pháp được mở). Nó được lưu trữ trong một biến toàn cục _applicationObject trong lớp kết nối bổ trợ của bạn. Nó được đặt khi bổ trợ của bạn bắt đầu trong trình xử lý sự kiện OnConnection.Vì vậy, tất cả những gì bạn cần là gọi:

string solutionDir = System.IO.Path.GetDirectoryName(_applicationObject.Solution.FullName); 
+0

Cảm ơn Peter, đó chính xác là vấn đề và giải pháp! Bây giờ tôi sẽ tìm cách để có được đầu ra từ thực hiện các công cụ thông qua các menu tùy chỉnh để đi đến cửa sổ đầu ra thay vì một cửa sổ riêng biệt và tất cả sẽ hoạt động hoàn hảo. Cảm ơn một lần nữa. –

6

Với việc Peter đẩy đúng hướng, tôi thiết lập menu ngữ cảnh addin để khởi chạy công cụ bên ngoài với thư mục giải pháp và xuất kết quả ra cửa sổ đầu ra. Một số ví dụ về sự gia tăng từ việc thêm vào:

///-------------------------------------------------------------------------------- 
    /// <summary>This method implements the OnConnection method of the IDTExtensibility2 interface. Receives notification that the Add-in is being loaded.</summary> 
    /// 
    /// <param term='application'>Root object of the host application.</param> 
    /// <param term='connectMode'>Describes how the Add-in is being loaded.</param> 
    /// <param term='addInInst'>Object representing this Add-in.</param> 
    /// <seealso class='IDTExtensibility2' /> 
    ///-------------------------------------------------------------------------------- 
    public void OnConnection(object application, ext_ConnectMode connectMode, object addInInst, ref Array custom) 
    { 
     _applicationObject = (DTE2)application; 
     _addInInstance = (AddIn)addInInst; 

     // Get the solution command bar 
     CommandBar solutionCommandBar = ((CommandBars)_applicationObject.CommandBars)["Solution"]; 

     // Set up the main InCode 
     CommandBarPopup solutionPopup = (CommandBarPopup)solutionCommandBar.Controls.Add(MsoControlType.msoControlPopup, System.Reflection.Missing.Value, System.Reflection.Missing.Value, 1, true); 
     solutionPopup.Caption = "InCode"; 

     // Add solution updater submenu 
     CommandBarControl solutionUpdaterControl = solutionPopup.Controls.Add(MsoControlType.msoControlButton, System.Reflection.Missing.Value, System.Reflection.Missing.Value, 1, true); 
     solutionUpdaterControl.Caption = "Update Solution"; 
     updateSolutionMenuItemHandler = (CommandBarEvents)_applicationObject.Events.get_CommandBarEvents(solutionUpdaterControl); 
     updateSolutionMenuItemHandler.Click += new _dispCommandBarControlEvents_ClickEventHandler(updateSolution_Click); 
    } 

    // The event handlers for the solution submenu items 
    CommandBarEvents updateSolutionMenuItemHandler; 

    ///-------------------------------------------------------------------------------- 
    /// <summary>This property gets the solution updater output pane.</summary> 
    ///-------------------------------------------------------------------------------- 
    protected OutputWindowPane _solutionUpdaterPane = null; 
    protected OutputWindowPane SolutionUpdaterPane 
    { 
     get 
     { 
      if (_solutionUpdaterPane == null) 
      { 
       OutputWindow outputWindow = _applicationObject.ToolWindows.OutputWindow; 
       foreach (OutputWindowPane loopPane in outputWindow.OutputWindowPanes) 
       { 
        if (loopPane.Name == "Solution Updater") 
        { 
         _solutionUpdaterPane = loopPane; 
         return _solutionUpdaterPane; 
        } 
       } 
       _solutionUpdaterPane = outputWindow.OutputWindowPanes.Add("Solution Updater"); 
      } 
      return _solutionUpdaterPane; 
     } 
    } 

    ///-------------------------------------------------------------------------------- 
    /// <summary>This method handles clicking on the Update Solution submenu.</summary> 
    /// 
    /// <param term='inputCommandBarControl'>The control that is source of the click.</param> 
    /// <param term='handled'>Handled flag.</param> 
    /// <param term='cancelDefault'>Cancel default flag.</param> 
    ///-------------------------------------------------------------------------------- 
    protected void updateSolution_Click(object inputCommandBarControl, ref bool handled, ref bool cancelDefault) 
    { 
     try 
     { 
      // set up and execute solution updater thread 
      UpdateSolutionDelegate updateSolutionDelegate = UpdateSolution; 
      updateSolutionDelegate.BeginInvoke(UpdateSolutionCompleted, updateSolutionDelegate); 
     } 
     catch (System.Exception ex) 
     { 
      // put exception message in output pane 
      SolutionUpdaterPane.OutputString(ex.Message); 
     } 
    } 

    protected delegate void UpdateSolutionDelegate(); 

    ///-------------------------------------------------------------------------------- 
    /// <summary>This method launches the solution updater to update the solution.</summary> 
    ///-------------------------------------------------------------------------------- 
    protected void UpdateSolution() 
    { 
     try 
     { 
      // set up solution updater process 
      string solutionDir = System.IO.Path.GetDirectoryName(_applicationObject.Solution.FullName); 
      System.Diagnostics.ProcessStartInfo procStartInfo = new System.Diagnostics.ProcessStartInfo(@"SolutionUpdater.exe", solutionDir); 
      procStartInfo.RedirectStandardOutput = true; 
      procStartInfo.UseShellExecute = false; 
      procStartInfo.CreateNoWindow = true; 
      System.Diagnostics.Process proc = new System.Diagnostics.Process(); 
      proc.StartInfo = procStartInfo; 

      // execute the solution updater 
      proc.Start(); 

      // put solution updater output to output pane 
      SolutionUpdaterPane.OutputString(proc.StandardOutput.ReadToEnd()); 
      SolutionUpdaterPane.OutputString("Solution update complete."); 
     } 
     catch (System.Exception ex) 
     { 
      // put exception message in output pane 
      SolutionUpdaterPane.OutputString(ex.Message); 
     } 
    } 

    ///-------------------------------------------------------------------------------- 
    /// <summary>This method completing the update solution thread.</summary> 
    /// 
    /// <param name="ar">IAsyncResult.</param> 
    ///-------------------------------------------------------------------------------- 
    protected void UpdateSolutionCompleted(IAsyncResult ar) 
    { 
     try 
     { 
      if (ar == null) throw new ArgumentNullException("ar"); 

      UpdateSolutionDelegate updateSolutionDelegate = ar.AsyncState as UpdateSolutionDelegate; 
      Trace.Assert(updateSolutionDelegate != null, "Invalid object type"); 

      updateSolutionDelegate.EndInvoke(ar); 
     } 
     catch (System.Exception ex) 
     { 
      // put exception message in output pane 
      SolutionUpdaterPane.OutputString(ex.Message); 
     } 
    } 
+0

Không, không tìm được cách để thăm dò ý kiến ​​một quy trình bên ngoài, tôi đã làm những gì tôi cần làm một quy trình nội bộ trong Gói VS. –

+0

Tôi có một giải pháp cho kết quả bỏ phiếu (hoặc thay luồng đầu ra vào ngăn đầu ra), ít nhất là khi sử dụng VSPackage. Thay vì phạm vi cho câu hỏi này (và sẽ không phù hợp ở đây ..), vì vậy có lẽ bạn có thể mở một câu hỏi mới và tôi sẽ trả lời ở đó. –

+0

OK, tôi đã ném một câu hỏi riêng cho câu hỏi này, nếu câu trả lời của bạn có vẻ tốt, tôi sẽ chấp nhận! http://stackoverflow.com/questions/8345636/is-there-a-good-way-to-stream-the-results-from-an-external-process-into-a-visual –

Các vấn đề liên quan