Question

J'ai quelques outils qui effectuent des mises à jour sur les solutions .NET, mais ils ont besoin de connaître le répertoire où se trouve la solution.

J'ai ajouté ces outils comme outils externes, où ils apparaissent dans le menu Outils IDE, et fournissant $(SolutionDir) comme argument. Cela fonctionne très bien.

Cependant, je veux que ces outils soient plus faciles d'accès dans l'EDI pour l'utilisateur via un menu de niveau supérieur personnalisé (pour lequel je créé un projet package d'intégration Visual Studio) et à travers un menu contextuel sur les nœuds de solution (pour laquelle je créé un Visual studio projet add-in). Je cherche un moyen d'obtenir le répertoire courant de solution dans ces contextes.

J'ai essayé d'obtenir les informations de la solution de l'objet VisualStudio.DTE:

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

Mais, cela renvoie le répertoire de solution pour les ins add, pas la solution actuelle.

J'ai essayé écho $(SolutionDir) et en les lisant:

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

Mais, ce retour dans le répertoire de l'IDE, pas la solution actuelle.

Je ne vois pas d'informations pertinentes dans le nœud de solution CommandBar.

Par ailleurs, s'il y avait un moyen d'accéder à la programmation des outils externes définis Visual Studio et les lancer (en utilisant les arguments macro déjà définis), qui fonctionnerait.

Quelle est la solution?

Était-ce utile?

La solution

  

EnvDTE.DTE dte =   (EnvDTE.DTE) System.Runtime.InteropServices.Marshal.GetActiveObject ( "VisualStudio.DTE");   = chaîne SolutionDir   System.IO.Path.GetDirectoryName (dte.Solution.FullName);

     

Mais, cela renvoie la solution   répertoire pour les ins add, pas   solution actuelle.

Votre approche pour obtenir le répertoire est bon. Quel est le problème est la façon dont vous obtenez l'objet VisualStudio.DTE. Où est-ce code appelé? Je suppose qu'il est dans votre complément. Exécutez-vous (debug) votre complément dans Visual Studio qui ouvre une autre instance de Visual Studio où vous ouvrez votre solution? Donc, vous avez deux instances de Visual Studio.

Le GetActiveObject("VisualStudio.DTE") obtient une instance Visual Studio aléatoire. Dans votre cas, il est apparemment Visual Studio avec un projet complément puisque vous obtenez chemin de votre complément. C'est pour expliquer ce qui serait la raison de votre problème.

La bonne façon d'obtenir DTE est très simple. En fait, votre complément a déjà référence à DTE dans lequel il fonctionne (c'est, dans lequel est ouvert la solution). Il est stocké dans une variable globale _applicationObject dans votre add-en classe de connexion. Il est défini lors de votre complément commence dans le gestionnaire d'événements OnConnection. Donc, tout ce dont vous avez besoin est d'appeler:

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

Autres conseils

Avec la poussée de Peter dans la bonne direction, je mis en place dans le menu contextuel Addin pour lancer un outil externe avec le répertoire de solution, et la sortie des résultats à la sous-fenêtre de sortie. Quelques exemples blurb de l'ajouter dans:

    ///--------------------------------------------------------------------------------
    /// <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);
        }
    }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top