2010-01-13 2 views
21

.NET 솔루션에 대한 업데이트를 수행하는 도구가 있지만 솔루션이있는 디렉터리를 알아야합니다.프로그래밍 방식으로 현재 Visual Studio IDE 솔루션 디렉터리를 추가 기능에서 가져 오기

이러한 도구를 외부 도구로 추가했습니다.이 도구는 IDE 도구 메뉴에 표시되고 $(SolutionDir)을 인수로 제공합니다. 이것은 잘 작동합니다.

그러나 Visual Studio 통합 패키지 프로젝트를 만든 사용자 지정 최상위 메뉴와 솔루션 노드의 상황에 맞는 메뉴를 통해이 도구를 IDE에서 쉽게 액세스 할 수 있기를 바랍니다. Visual Studio 추가 기능 프로젝트를 만들었습니다.) 이 컨텍스트를 통해 현재 솔루션 디렉토리를 얻는 방법을 찾고 있습니다.

은 내가 VisualStudio.DTE 개체에서 솔루션 정보를 가져 오는 시도 :

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

그러나, 이것은 추가 기능이 아닌 현재의 솔루션을 솔루션 디렉토리를 반환합니다. 이 아니라 현재 솔루션의 IDE에 대한 디렉토리를 반환,

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(); 

을하지만 :

나는 $(SolutionDir)를 반향하고 그것을 다시 읽어했습니다.

솔루션 노드 CommandBar에서 관련 정보를 찾지 못했습니다.

또는 정의 된 Visual Studio 외부 도구에 프로그래밍 방식으로 액세스하여 이미 정의 된 매크로 인수를 사용하여 시작할 수있는 방법이 있으면 작동합니다.

해결책은 무엇입니까?

+0

분명히 나는이 DTE 광기 롤 – Terrance

답변

18

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

그러나이 방법은 현재 솔루션이 아닌 추가 기능에 대한 솔루션 디렉터리를 반환합니다.

디렉토리를 얻는 방법이 좋습니다. 무엇이 잘못되었는지는 VisualStudio.DTE 개체를 얻는 방법입니다. 이 코드는 어디에서 호출됩니까? 귀하의 추가 기능에 있다고 가정합니다. Visual Studio에서 솔루션을 여는 Visual Studio의 다른 인스턴스를 여는 추가 기능을 실행 (디버깅)합니까? 따라서 Visual Studio 인스턴스가 두 개 있습니다.

GetActiveObject("VisualStudio.DTE")은 임의의 Visual Studio 인스턴스를 가져옵니다. 귀하의 경우에는 추가 기능에 대한 경로를 얻은 이후로 추가 기능 프로젝트가있는 Visual Studio가 설치되어있는 것 같습니다. 그것은 당신의 문제의 원인이 무엇인지에 대한 설명입니다.

DTE을 얻는 올바른 방법은 매우 간단합니다. 실제로 추가 기능에는 이미 실행되는 DTE (즉, 솔루션이 열리는)에 대한 참조가 있습니다. 추가 기능 연결 클래스의 전역 변수 _applicationObject에 저장됩니다. 추가 기능이 OnConnection 이벤트 처리기에서 시작될 때 설정됩니다.그래서 당신이 필요로하는 모든 호출하는 것입니다

올바른 방향으로 베드로의 푸시와
string solutionDir = System.IO.Path.GetDirectoryName(_applicationObject.Solution.FullName); 
+0

감사 피터와 함께 당신을 스토킹하고있어 다시 2+, 즉 정확하게 문제 및 솔루션이었다! 이제 별도의 창 대신 출력 창으로 이동하기 위해 사용자 지정 메뉴를 통해 도구를 실행하는 결과물을 얻는 방법을 찾고 모든 것이 완벽하게 작동합니다. 다시 한번 감사드립니다. –

6

, 나는 외부 솔루션 디렉토리와 도구, 출력 출력 창에 결과를 실행 컨텍스트 메뉴 추가 기능을 설정합니다. 에서 추가 기능의 일부 예를 들어 추천 광고 :

///-------------------------------------------------------------------------------- 
    /// <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

아니, 외부 프로세스를 폴링하는 방법을 찾지 못해서 VS 패키지의 내부 프로세스로 필요한 작업을 수행했습니다. –

+0

적어도 VSPackage를 사용할 때 결과 폴링 (또는 출력 창으로 출력 스트림 전송)을위한 솔루션이 있습니다. 이 질문의 범위를 벗어나서 (여기에 맞지는 않을 것입니다.) 아마도 새로운 질문을 열어서 대답 할 것입니다. –

+0

당신의 대답이 좋아 보인다면 OK, 나는 이것에 대한 별도의 질문을 함께 던졌다. 나는 받아 들일 것이다! http://stackoverflow.com/questions/8345636/is-there-a-good-way-to-stream-the-results-from-an-external-process-into-visual –

관련 문제