Announcement

Collapse
No announcement yet.

Compare code in Visual Studio IDE

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Compare code in Visual Studio IDE

    I have recently set up to use BC in SourceSafe and it works great.

    Often when working in Visual Studio (2005/2008) I have the need to compare two files in the project. I would like to be able to select the files in the solution explorer, right-click and select some sort of 'Compare with BC' command.

    Does anyone have experience trying this?

  • #2
    Re: Compare code in Visual Studio IDE

    I wasn't content to sit and wait, and I was able to figure out how to do it. To do it, create a Visual Studio Add-In project (I called mine BCCompare). I used C#. The code for Connect.cs follows. Everyone is welcome to it, and Scooter can post the plugin if they find it worthy.



    using System;
    using System.Diagnostics;
    using System.IO;
    using System.Windows.Forms;
    using EnvDTE;
    using EnvDTE80;
    using Extensibility;
    using Microsoft.VisualStudio.CommandBars;
    using Microsoft.Win32;



    namespace BCCompare
    {
    /// <summary>The object for implementing an Add-in.</summary>
    /// <seealso class='IDTExtensibility2' />
    public class Connect : IDTExtensibility2, IDTCommandTarget
    {
    /// <summary>Implements the constructor for the Add-in object. Place your initialization code within this method.</summary>
    public Connect ()
    {
    }

    /// <summary>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;
    if (connectMode == Extensibility.ext_ConnectMode.ext_cm_Startup)
    {
    Command command;
    CommandBar itemCmdBar;
    object[] contextGUIDS = new object[] { };
    try
    {
    // Create a Command with name SolnExplContextMenuCS and then add it to the "Item" menubar for the SolutionExplorer
    command = _applicationObject.Commands.AddNamedCommand(_addIn Instance, "BCCompare", "Compare using Beyond Compare", "Compares two selected files using Beyond Compare", false, 0, ref contextGUIDS, (int) vsCommandStatus.vsCommandStatusSupported + (int) vsCommandStatus.vsCommandStatusEnabled);
    itemCmdBar = ((CommandBars) _applicationObject.CommandBars)["Item"];
    if (itemCmdBar == null)
    {
    System.Windows.Forms.MessageBox.Show("Cannot get the Item menubar", "Error", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
    }
    else
    {
    command.AddControl(itemCmdBar, 1);
    }
    }
    catch (Exception ex)
    {
    System.Windows.Forms.MessageBox.Show(ex.ToString() , "Error", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
    }
    }
    }

    /// <summary>Implements the OnDisconnection method of the IDTExtensibility2 interface. Receives notification that the Add-in is being unloaded.</summary>
    /// <param term='disconnectMode'>Describes how the Add-in is being unloaded.</param>
    /// <param term='custom'>Array of parameters that are host application specific.</param>
    /// <seealso class='IDTExtensibility2' />
    public void OnDisconnection (ext_DisconnectMode disconnectMode, ref Array custom)
    {
    }

    /// <summary>Implements the OnAddInsUpdate method of the IDTExtensibility2 interface. Receives notification when the collection of Add-ins has changed.</summary>
    /// <param term='custom'>Array of parameters that are host application specific.</param>
    /// <seealso class='IDTExtensibility2' />
    public void OnAddInsUpdate (ref Array custom)
    {
    }

    /// <summary>Implements the OnStartupComplete method of the IDTExtensibility2 interface. Receives notification that the host application has completed loading.</summary>
    /// <param term='custom'>Array of parameters that are host application specific.</param>
    /// <seealso class='IDTExtensibility2' />
    public void OnStartupComplete (ref Array custom)
    {
    }

    /// <summary>Implements the OnBeginShutdown method of the IDTExtensibility2 interface. Receives notification that the host application is being unloaded.</summary>
    /// <param term='custom'>Array of parameters that are host application specific.</param>
    /// <seealso class='IDTExtensibility2' />
    public void OnBeginShutdown (ref Array custom)
    {
    }

    private DTE2 _applicationObject;
    private AddIn _addInInstance;

    #region IDTCommandTarget Members

    /// <summary>Implements the Exec method of the IDTCommandTarget interface. This is called when the command is invoked.</summary>
    /// <param term='CmdName'>The name of the command to execute.</param>
    /// <param term='ExecuteOption'>Describes how the command should be run.</param>
    /// <param term='VariantIn'>Parameters passed from the caller to the command handler.</param>
    /// <param term='VariantOut'>Parameters passed from the command handler to the caller.</param>
    /// <param term='Handled'>Informs the caller if the command was handled or not.</param>
    /// <seealso class='Exec' />
    public void Exec (string CmdName, vsCommandExecOption ExecuteOption, ref object VariantIn, ref object VariantOut, ref bool Handled)
    {
    Handled = false;
    if (ExecuteOption == vsCommandExecOption.vsCommandExecOptionDoDefault)
    {
    if (CmdName == "BCCompare.Connect.BCCompare")
    {
    UIHierarchy UIH = _applicationObject.ToolWindows.SolutionExplorer;
    UIHierarchyItems uihItems = UIH.UIHierarchyItems;
    Array aoItems = UIH.SelectedItems as Array;
    if (aoItems != null && aoItems.Length == 2)
    {
    String strFile1 = String.Empty;
    UIHierarchyItem item1 = aoItems.GetValue(0) as UIHierarchyItem;
    ProjectItem prj1 = item1.Object as ProjectItem;
    if (prj1.Kind == EnvDTE.Constants.vsProjectItemKindPhysicalFile) {
    String strProjectFolder = String.Empty;
    try
    {
    strProjectFolder = prj1.ContainingProject.Properties.Item("FullPath") .Value.ToString();
    }
    catch (ArgumentException)
    {
    // don't know why it didn't work, but if it does throw, try alternative
    strProjectFolder = Path.GetDirectoryName(prj1.ContainingProject.FullN ame);
    }
    strFile1 = Path.Combine(strProjectFolder, item1.Name);
    }

    String strFile2 = String.Empty;
    UIHierarchyItem item2 = aoItems.GetValue(1) as UIHierarchyItem;
    ProjectItem prj2 = item2.Object as ProjectItem;
    if (prj2.Kind == EnvDTE.Constants.vsProjectItemKindPhysicalFile)
    {
    String strProjectFolder = String.Empty;
    try
    {
    strProjectFolder = prj2.ContainingProject.Properties.Item("FullPath") .Value.ToString();
    }
    catch (ArgumentException)
    {
    // don't know why it didn't work, but if it does throw, try alternative
    strProjectFolder = Path.GetDirectoryName(prj2.ContainingProject.FullN ame);
    }
    strFile2 = Path.Combine(strProjectFolder, item2.Name);
    }


    RegistryKey keyBeyondCompare = Registry.CurrentUser.OpenSubKey(@"Software\Scooter Software\Beyond Compare");
    String strExePath = (String) keyBeyondCompare.GetValue("ExePath");

    ProcessStartInfo psi = new ProcessStartInfo();
    psi.FileName = strExePath;
    psi.Arguments = String.Format("\"{0}\" \"{1}\"", strFile1, strFile2);
    if (System.Diagnostics.Process.Start(psi) == null)
    MessageBox.Show("Could not launch compare.", "Cannot launch compare", MessageBoxButtons.OK, MessageBoxIcon.Warning);
    }
    Handled = true;
    return;
    }
    }
    }

    /// <summary>Implements the QueryStatus method of the IDTCommandTarget interface. This is called when the command's availability is updated</summary>
    /// <param term='CmdName'>The name of the command to determine state for.</param>
    /// <param term='NeededText'>Text that is needed for the command.</param>
    /// <param term='StatusOption'>The state of the command in the user interface.</param>
    /// <param term='CommandText'>Text requested by the neededText parameter.</param>
    /// <seealso class='Exec' />
    public void QueryStatus (String strCmdName, vsCommandStatusTextWanted NeededText, ref vsCommandStatus StatusOption, ref object CommandText)
    {
    if (NeededText == vsCommandStatusTextWanted.vsCommandStatusTextWante dNone)
    {
    if (strCmdName == "BCCompare.Connect.BCCompare")
    {
    UIHierarchy UIH = _applicationObject.ToolWindows.SolutionExplorer;
    Array aoItems = UIH.SelectedItems as Array;
    if (aoItems != null && aoItems.Length == 2)
    {
    String strFile1 = String.Empty;
    UIHierarchyItem item1 = aoItems.GetValue(0) as UIHierarchyItem;
    ProjectItem prj1 = item1.Object as ProjectItem;
    if (prj1.Kind == EnvDTE.Constants.vsProjectItemKindPhysicalFile)
    {
    String strProjectFolder = String.Empty;
    try
    {
    strProjectFolder = prj1.ContainingProject.Properties.Item("FullPath") .Value.ToString();
    }
    catch (ArgumentException)
    {
    // don't know why it didn't work, but if it does throw, try alternative
    strProjectFolder = Path.GetDirectoryName(prj1.ContainingProject.FullN ame);
    }
    strFile1 = Path.Combine(strProjectFolder, item1.Name);
    }

    String strFile2 = String.Empty;
    UIHierarchyItem item2 = aoItems.GetValue(1) as UIHierarchyItem;
    ProjectItem prj2 = item2.Object as ProjectItem;
    if (prj2.Kind == EnvDTE.Constants.vsProjectItemKindPhysicalFile)
    {
    String strProjectFolder = String.Empty;
    try
    {
    strProjectFolder = prj2.ContainingProject.Properties.Item("FullPath") .Value.ToString();
    }
    catch (ArgumentException)
    {
    // don't know why it didn't work, but if it does throw, try alternative
    strProjectFolder = Path.GetDirectoryName(prj2.ContainingProject.FullN ame);
    }
    strFile2 = Path.Combine(strProjectFolder, item2.Name);
    }


    RegistryKey keyBeyondCompare = Registry.CurrentUser.OpenSubKey(@"Software\Scooter Software\Beyond Compare");
    String strExePath = (String) keyBeyondCompare.GetValue("ExePath");

    if (File.Exists(strExePath) && File.Exists(strFile1) && File.Exists(strFile2))
    {
    StatusOption = vsCommandStatus.vsCommandStatusSupported;
    StatusOption |= vsCommandStatus.vsCommandStatusEnabled;
    }
    else
    {
    StatusOption = vsCommandStatus.vsCommandStatusUnsupported;
    StatusOption |= vsCommandStatus.vsCommandStatusInvisible;
    }
    }
    else
    {
    StatusOption = vsCommandStatus.vsCommandStatusUnsupported;
    StatusOption |= vsCommandStatus.vsCommandStatusInvisible;
    }
    }
    else
    {
    StatusOption = vsCommandStatus.vsCommandStatusUnsupported;
    }
    }
    }
    #endregion
    }
    }

    Comment


    • #3
      Hi Sparticus1701,

      Thanks for posting your solution here.

      Kevin Sikes

      Comment


      • #4
        I have VS 2008, but am not sure how to create a Visual Studio add-in.
        Would you mind zipping up the solution and attaching the .zip file?
        BC v4.0.7 build 19761
        ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯

        Comment


        • #5
          Hi Guys,

          Is anybody able to use Sparticus1701 code above and create a Visual Studio 2010 version? ..with the same functionality he mentioned before "to be able to select the files in the solution explorer, right-click and select some sort of 'Compare with BC' command."

          Thank you.

          Comment

          Working...
          X