Pregunta

Tengo algunas herramientas que realizan cambios en las soluciones .NET, pero necesito saber el directorio donde se encuentra la solución.

He añadido estas herramientas como herramientas externas, en las que aparecen en el menú Herramientas IDE, y el suministro de $(SolutionDir) como argumento. Esto funciona bien.

Sin embargo, quiero que estas herramientas sean más fáciles de acceder en el IDE para el usuario a través de un menú de nivel superior de encargo (para el que he creado un proyecto de paquete de integración de Visual Studio) ya través de un menú contextual de los nodos de la solución (para lo cual creado un proyecto de complemento de Visual Studio). Estoy buscando una manera de obtener el directorio actual solución a través de estos contextos.

He intentado obtener la información solución del objeto VisualStudio.DTE:

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

Sin embargo, este resultado el directorio solución para los complementos complementos, no la solución actual.

He intentado eco $(SolutionDir) y leer de nuevo:

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

Sin embargo, esto devolverá el directorio para el IDE, no la solución actual.

No he visto ninguna información relevante en el CommandBar nodo de la solución.

Por otra parte, si había una manera de tener acceso mediante programación las herramientas externas de Visual Studio definidos y lanzarlos (usando los argumentos de la macro ya definidos), que iba a funcionar.

¿Cuál es la solución?

¿Fue útil?

Solución

  

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

     

Sin embargo, esto devuelve la solución   directorio para los complementos complementos, no el   solución actual.

Su enfoque para obtener el directorio es bueno. Lo que está mal es la manera de conseguir el objeto VisualStudio.DTE. Cuando se llama a este código? Asumo que es en su complemento. Cómo se ejecuta (depuración) su complemento en Visual Studio que se abre otra instancia de Visual Studio en el que abre su solución? Así que hay dos instancias de Visual Studio.

El GetActiveObject("VisualStudio.DTE") consigue un ejemplo al azar de Visual Studio. En su caso, es al parecer Visual Studio con un proyecto de complemento ya que te dan ruta a su complemento. Esa es la explicación de lo que sería la causa de su problema.

La forma correcta para conseguir DTE es muy simple. De hecho, el complemento ya con referencia a DTE en el que se ejecuta (es decir, en la que se abre la solución). Se almacena en una variable global _applicationObject en su clase de conexión complemento. Se establece cuando el complemento se inicia en el controlador de eventos OnConnection. Así que todo lo que necesita es llamar a:

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

Otros consejos

Con el empuje de Pedro en la dirección correcta, he creado el complemento menú contextual para lanzar una herramienta externa con el directorio de la solución, y la salida de los resultados al panel de salida. Algunos ejemplos blurb del complemento en:

    ///--------------------------------------------------------------------------------
    /// <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);
        }
    }
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top