Advertisement
eugene-gubenkov

Reference Doctor - Replaces file references by project

Dec 26th, 2013
193
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 12.60 KB | None | 0 0
  1. using System;
  2. using Extensibility;
  3. using EnvDTE;
  4. using EnvDTE80;
  5. using Microsoft.VisualStudio.CommandBars;
  6. using System.Resources;
  7. using System.Reflection;
  8. using System.Globalization;
  9. using VSLangProj;
  10. using System.IO;
  11.  
  12. namespace ReferenceDoctor
  13. {
  14.     /// <summary>The object for implementing an Add-in.</summary>
  15.     /// <seealso class='IDTExtensibility2' />
  16.     public class Connect : IDTExtensibility2, IDTCommandTarget
  17.     {
  18.         private StreamWriter _logWriter;
  19.  
  20.         /// <summary>Implements the constructor for the Add-in object. Place your initialization code within this method.</summary>
  21.         public Connect()
  22.         {
  23.         }
  24.  
  25.         /// <summary>Implements the OnConnection method of the IDTExtensibility2 interface. Receives notification that the Add-in is being loaded.</summary>
  26.         /// <param term='application'>Root object of the host application.</param>
  27.         /// <param term='connectMode'>Describes how the Add-in is being loaded.</param>
  28.         /// <param term='addInInst'>Object representing this Add-in.</param>
  29.         /// <seealso class='IDTExtensibility2' />
  30.         public void OnConnection(object application, ext_ConnectMode connectMode, object addInInst, ref Array custom)
  31.         {
  32.             _applicationObject = (DTE2)application;
  33.             _addInInstance = (AddIn)addInInst;          
  34.             if(connectMode == ext_ConnectMode.ext_cm_UISetup)
  35.             {
  36.                 object []contextGUIDS = new object[] { };
  37.                 Commands2 commands = (Commands2)_applicationObject.Commands;
  38.                 string toolsMenuName = "Tools";
  39.  
  40.                 //Place the command on the tools menu.
  41.                 //Find the MenuBar command bar, which is the top-level command bar holding all the main menu items:
  42.                 Microsoft.VisualStudio.CommandBars.CommandBar menuBarCommandBar = ((Microsoft.VisualStudio.CommandBars.CommandBars)_applicationObject.CommandBars)["MenuBar"];
  43.  
  44.                 //Find the Tools command bar on the MenuBar command bar:
  45.                 CommandBarControl toolsControl = menuBarCommandBar.Controls[toolsMenuName];
  46.                 CommandBarPopup toolsPopup = (CommandBarPopup)toolsControl;
  47.  
  48.                 //This try/catch block can be duplicated if you wish to add multiple commands to be handled by your Add-in,
  49.                 //  just make sure you also update the QueryStatus/Exec method to include the new command names.
  50.                 try
  51.                 {
  52.                     //Add a command to the Commands collection:
  53.                     Command command = commands.AddNamedCommand2(
  54.                         _addInInstance,
  55.                         "ReferenceDoctor",
  56.                         "ReferenceDoctor",
  57.                         "Executes the command for ReferenceDoctor",
  58.                         true,
  59.                         59,
  60.                         ref contextGUIDS,
  61.                         (int)vsCommandStatus.vsCommandStatusSupported+(int)vsCommandStatus.vsCommandStatusEnabled,
  62.                         (int)vsCommandStyle.vsCommandStylePictAndText,
  63.                         vsCommandControlType.vsCommandControlTypeButton);
  64.  
  65.                     //Add a control for the command to the tools menu:
  66.                     if((command != null) && (toolsPopup != null))
  67.                     {
  68.                         command.AddControl(toolsPopup.CommandBar, 1);
  69.                     }
  70.                 }
  71.                 catch(System.ArgumentException)
  72.                 {
  73.                     //If we are here, then the exception is probably because a command with that name
  74.                     //  already exists. If so there is no need to recreate the command and we can
  75.                     //  safely ignore the exception.
  76.                 }
  77.             }
  78.         }
  79.  
  80.         /// <summary>Implements the OnDisconnection method of the IDTExtensibility2 interface. Receives notification that the Add-in is being unloaded.</summary>
  81.         /// <param term='disconnectMode'>Describes how the Add-in is being unloaded.</param>
  82.         /// <param term='custom'>Array of parameters that are host application specific.</param>
  83.         /// <seealso class='IDTExtensibility2' />
  84.         public void OnDisconnection(ext_DisconnectMode disconnectMode, ref Array custom)
  85.         {
  86.             _logWriter.Close();
  87.         }
  88.  
  89.         /// <summary>Implements the OnAddInsUpdate method of the IDTExtensibility2 interface. Receives notification when the collection of Add-ins has changed.</summary>
  90.         /// <param term='custom'>Array of parameters that are host application specific.</param>
  91.         /// <seealso class='IDTExtensibility2' />      
  92.         public void OnAddInsUpdate(ref Array custom)
  93.         {
  94.         }
  95.  
  96.         /// <summary>Implements the OnStartupComplete method of the IDTExtensibility2 interface. Receives notification that the host application has completed loading.</summary>
  97.         /// <param term='custom'>Array of parameters that are host application specific.</param>
  98.         /// <seealso class='IDTExtensibility2' />
  99.         public void OnStartupComplete(ref Array custom)
  100.         {
  101.         }
  102.  
  103.         /// <summary>Implements the OnBeginShutdown method of the IDTExtensibility2 interface. Receives notification that the host application is being unloaded.</summary>
  104.         /// <param term='custom'>Array of parameters that are host application specific.</param>
  105.         /// <seealso class='IDTExtensibility2' />
  106.         public void OnBeginShutdown(ref Array custom)
  107.         {
  108.         }
  109.        
  110.         /// <summary>Implements the QueryStatus method of the IDTCommandTarget interface. This is called when the command's availability is updated</summary>
  111.         /// <param term='commandName'>The name of the command to determine state for.</param>
  112.         /// <param term='neededText'>Text that is needed for the command.</param>
  113.         /// <param term='status'>The state of the command in the user interface.</param>
  114.         /// <param term='commandText'>Text requested by the neededText parameter.</param>
  115.         /// <seealso class='Exec' />
  116.         public void QueryStatus(string commandName, vsCommandStatusTextWanted neededText, ref vsCommandStatus status, ref object commandText)
  117.         {
  118.             if(neededText == vsCommandStatusTextWanted.vsCommandStatusTextWantedNone)
  119.             {
  120.                 if(commandName == "ReferenceDoctor.Connect.ReferenceDoctor")
  121.                 {
  122.                     status = (vsCommandStatus)vsCommandStatus.vsCommandStatusSupported|vsCommandStatus.vsCommandStatusEnabled;
  123.                     return;
  124.                 }
  125.             }
  126.         }
  127.  
  128.         /// <summary>Implements the Exec method of the IDTCommandTarget interface. This is called when the command is invoked.</summary>
  129.         /// <param term='commandName'>The name of the command to execute.</param>
  130.         /// <param term='executeOption'>Describes how the command should be run.</param>
  131.         /// <param term='varIn'>Parameters passed from the caller to the command handler.</param>
  132.         /// <param term='varOut'>Parameters passed from the command handler to the caller.</param>
  133.         /// <param term='handled'>Informs the caller if the command was handled or not.</param>
  134.         /// <seealso class='Exec' />
  135.         public void Exec(string commandName, vsCommandExecOption executeOption, ref object varIn, ref object varOut, ref bool handled)
  136.         {
  137.             handled = false;
  138.  
  139.             LogMessage(string.Format("Start investigation at {0} {1}", DateTime.Now.ToLongDateString(), DateTime.Now.ToLongTimeString()));
  140.  
  141.             if(executeOption == vsCommandExecOption.vsCommandExecOptionDoDefault)
  142.             {
  143.                 if(commandName == "ReferenceDoctor.Connect.ReferenceDoctor")
  144.                 {
  145.                     foreach (Project project in _applicationObject.Solution.Projects)
  146.                     {
  147.                         VSProject vsProject = project.Object as VSProject;
  148.                         if (vsProject != null)
  149.                         {
  150.                             foreach (Reference reference in vsProject.References)
  151.                             {
  152.                                 // if it not project reference
  153.                                 if (reference.SourceProject == null)
  154.                                 {
  155.                                     string refPath = reference.Path;
  156.                                     string refAssemblyName = Path.GetFileNameWithoutExtension(refPath);
  157.  
  158.                                     Project refProject = FindProjectWithinSolution(refAssemblyName);
  159.  
  160.                                     // if within solution found project with suitable name
  161.                                     if (refProject != null)
  162.                                     {
  163.                                         try
  164.                                         {
  165.                                             //replace reference with project reference
  166.                                             reference.Remove();
  167.                                             vsProject.References.AddProject(refProject);
  168.  
  169.                                             LogMessage(string.Format(" [{0}] Reference to {1} replaced. ({2} -> {3})", vsProject.Project.Name, refAssemblyName, refPath, refProject.FullName));
  170.                                         }
  171.                                         catch (Exception exc)
  172.                                         {
  173.                                             LogMessage(string.Format(" [{0}] ERROR during replacing reference to {1} ({2} -> {3}): {4}", vsProject.Project.Name, refAssemblyName, refPath, refProject.FullName, exc.Message));
  174.                                         }
  175.                                     }
  176.                                 }
  177.                             }
  178.                         }
  179.                     }
  180.  
  181.                     LogMessage(string.Format("Completed at {0} {1}\r\n", DateTime.Now.ToLongDateString(), DateTime.Now.ToLongTimeString()));
  182.                     //logWriter.WriteLine(string.Format("COMPLETED, {0} at {1}\r\n", DateTime.Now.ToLongDateString(), DateTime.Now.ToLongTimeString()));
  183.                     //logWriter.Dispose();
  184.  
  185.                     handled = true;
  186.                 }
  187.             }
  188.         }
  189.  
  190.         private Project FindProjectWithinSolution(string projectName)
  191.         {
  192.             foreach (Project project in _applicationObject.Solution.Projects)
  193.             {
  194.                 VSProject vsProject = project.Object as VSProject;
  195.                 if (vsProject != null)
  196.                 {
  197.                     if (string.Compare(vsProject.Project.Name, projectName, ignoreCase: true) == 0)
  198.                     {
  199.                         return project;
  200.                     }
  201.                 }
  202.             }
  203.  
  204.             return null;
  205.         }
  206.  
  207.         private void LogMessage(string str)
  208.         {
  209.             try
  210.             {
  211.                 LogToFile(str);
  212.             }
  213.             catch { }
  214.  
  215.             try
  216.             {
  217.                 LogToOutputWindow(str);
  218.             }
  219.             catch { }
  220.         }
  221.  
  222.         private void LogToFile(string str)
  223.         {
  224.             if (_logWriter == null)
  225.             {
  226.                 _logWriter = new StreamWriter(Path.Combine(new FileInfo(_applicationObject.Solution.FullName).DirectoryName, "ReferenceDoctor.log"), true);
  227.             }
  228.  
  229.             _logWriter.WriteLine(str);
  230.  
  231.             _logWriter.Flush();
  232.         }
  233.  
  234.         private void LogToOutputWindow(string str)
  235.         {
  236.             const string PANE_NAME = "Reference Doctor";
  237.  
  238.             OutputWindow ow = _applicationObject.ToolWindows.OutputWindow;
  239.  
  240.             if (!IsPaneExists(PANE_NAME))
  241.             {
  242.                 ow.OutputWindowPanes.Add(PANE_NAME);
  243.             }
  244.  
  245.             OutputWindowPane owP = _applicationObject.ToolWindows.OutputWindow.OutputWindowPanes.Item(PANE_NAME);
  246.  
  247.             owP.OutputString(str + Environment.NewLine);
  248.  
  249.             //Window window = _applicationObject.Windows.Item(EnvDTE.Constants.vsWindowKindOutput);
  250.             //OutputWindow outputWindow = (OutputWindow)window.Object;
  251.             //outputWindow.ActivePane.Activate();
  252.             //outputWindow.ActivePane.OutputString(str);
  253.         }
  254.  
  255.         private bool IsPaneExists(string name)
  256.         {
  257.             try
  258.             {
  259.                 var pane = _applicationObject.ToolWindows.OutputWindow.OutputWindowPanes.Item(name);
  260.  
  261.                 return true;
  262.             }
  263.             catch (Exception)
  264.             {
  265.                 return false;
  266.             }
  267.         }
  268.  
  269.         private DTE2 _applicationObject;
  270.         private AddIn _addInInstance;
  271.     }
  272. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement