Click here to Skip to main content
15,894,825 members
Articles / Programming Languages / C#

Visual Studio 2010 Add-in that Adds Diff Tools, Web Project Reporting and Some Subversion Support

Rate me:
Please Sign up or sign in to vote.
4.56/5 (13 votes)
12 May 2010CPOL4 min read 163.1K   2.7K   98  
With this add-in, you get new tools and commands that boost your productivity while developing, and some helpful reports especially for web projects - Version 2.2
��// Connect.cs

// This class connects the Webreports8 Add-in to the Visual Studion instance it's running in.

// Copyright by Matthias Hertel, http://www.mathertel.de

// This work is licensed under a Creative Commons Attribution 2.0 Germany License.

// See http://creativecommons.org/licenses/by/2.0/de/

// ----- 

// 31.01.2006 created by Matthias Hertel

// 17.03.2006 fixed: solutionEvents added to the class. see http://www.mztools.com/articles/2005/MZ012.htm

// 17.03.2006 the applicationObject reference is given up in the OnDisconnection event handling to make id garbage collectable.

// 17.03.2006 some dead code deleted.



using System;

using Extensibility;

using EnvDTE;

using EnvDTE80;

using Microsoft.VisualStudio.CommandBars;

using System.Resources;

using System.Reflection;

using System.Globalization;



using System.Collections;

using System.Collections.Specialized;

using System.IO;

using System.Runtime.InteropServices;

using System.Text;

using System.Text.RegularExpressions;

using System.Windows.Forms;



using SHDocVw;

using mshtml;



namespace WebReports8 {



  /// <summary>The object for implementing an Add-in.</summary>

  /// <seealso class='IDTExtensibility2' />

  public class Connect : IDTExtensibility2, IDTCommandTarget {



    /// <summary>

    /// The host application.

    /// </summary>

    public static DTE2 applicationObject; // static, because it is used from static methods.

    private AddIn addInInstance;



    EnvDTE.SolutionEvents solutionEvents;

    _dispSolutionEvents_OpenedEventHandler hOpened;

    _dispSolutionEvents_QueryCloseSolutionEventHandler hQueryCloseSolution;



    EnvDTE.Window windowToolWindow;

    SHDocVw.WebBrowser Browser = null;



    string rootPath;

    object nullObj = null;

    object oMissing = System.Reflection.Missing.Value;



    /// <summary>Namespace of the Add-In Commands and the window title</summary>

    public const string COMMANDBARNAME = "WebReports";



    /// <summary>Namespace of the Add-In Commands and the window title</summary>

    public const string COMMANDNAMESPACE = "WebReports8.Connect";



    /// <summary>Name of the Tools menu for the Diff commands</summary>

    const string DIFFMENU = "Diff Tools";



    /// <summary>Name of the Tools menu for the reports</summary>

    const string WEBTOOLSMENU = "Web Reports";



    const string EXPLORE_NAME = "Explore";

    const string EXPLORE_CAPTION = "Open Folder";



    const string FILEDIFF_NAME = "Diff";

    const string FILEDIFF_CAPTION = "File Differences";



    const string FOLDERDIFF_NAME = "DiffFolder";

    const string FOLDERDIFF_CAPTION = "Folder Differences";



    const string MAKEPATCH_NAME = "MakePatch";

    const string MAKEPATCH_CAPTION = "Make Patch";



    const string XSLT_NAME = "XsltTransform";

    const string XSLT_CAPTION = "Xslt Transformation";



    const string BACKUP_NAME = "Backup";

    const string BACKUP_CAPTION = "Backup";



    const string OPTION_NAME = "Option";

    const string OPTION_CAPTION = "Option";



    const string OLDEST_NAME = "Oldest";

    const string OLDEST_CAPTION = "Oldest files";



    const string NEWEST_NAME = "Newest";

    const string NEWEST_CAPTION = "Recently changed files";



    const string FILEBYTYPE_NAME = "FileByType";

    const string FILEBYTYPE_CAPTION = "File Types";



    // a stack for all commands so they can be repeated

    string LastCommand = String.Empty;

    StringCollection CommandStack = new StringCollection();



    bool registerCommandBar = false;



    /// <summary>Indicates that the commands are registered and connected.</summary>

    bool isConnected = false;



    /// <summary>Number of currently scrolled pixel when a reload command is executed.</summary>

    int BrowserScrollTop = 0;    

    



    /// <summary>Implements the constructor for the Add-in object.</summary>

    public Connect() {

      rootPath = System.Reflection.Assembly.GetExecutingAssembly().Location;

      rootPath = rootPath.Substring(0, rootPath.LastIndexOf('\\'));



      this.hOpened = null;

      this.hQueryCloseSolution = null;

      this.solutionEvents = null;

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

      Object nil = System.Reflection.Missing.Value;



      System.Diagnostics.Debug.Write(connectMode.ToString() + "\n", "OnConnection"); 

      

      if (connectMode == ext_ConnectMode.ext_cm_UISetup) {



      } else if ((!isConnected)

        && ((connectMode == Extensibility.ext_ConnectMode.ext_cm_Startup)

            || (connectMode == Extensibility.ext_ConnectMode.ext_cm_AfterStartup))) {



        try {

          CommandBar ToolsCmdBar = ((CommandBars)(applicationObject.CommandBars))["Tools"];

          CommandBarPopup popUp;

          Command cmd;



          CommandBar cmdBar = null;

          CommandBar webMenu = null;

          CommandBar diffMenu = null;



          if (registerCommandBar)

            cmdBar =  CommandHelper.AddCommandBar(applicationObject, COMMANDBARNAME);



          // Create the Tools menu for the diff commands

          popUp = (CommandBarPopup)ToolsCmdBar.Controls.Add(MsoControlType.msoControlPopup, oMissing, oMissing, 1, oMissing);

          popUp.Caption = DIFFMENU;

          diffMenu = popUp.CommandBar;



          // Create the Tools menu for the report commands

          popUp = (CommandBarPopup)ToolsCmdBar.Controls.Add(MsoControlType.msoControlPopup, oMissing, oMissing, 2, oMissing);

          popUp.Caption = WEBTOOLSMENU;

          webMenu = popUp.CommandBar;



          // get popUp command bars where commands will be registered.

          CommandBars cmdBars = (CommandBars)(applicationObject.CommandBars);

          CommandBar vsBarItem = cmdBars["Item"];

          CommandBar vsBarWebItem = cmdBars["Web Item"];

          CommandBar vsBarMultiItem = cmdBars["Cross Project Multi Item"];

          CommandBar vsBarFolder = cmdBars["Folder"];

          CommandBar vsBarWebFolder = cmdBars["Web Folder"];

          CommandBar vsBarProject = cmdBars["Project"];

          CommandBar vsBarProjectNode = cmdBars["Project Node"];



          CommandHelper.AddCommand(applicationObject, addInInstance, FILEBYTYPE_NAME, 2, FILEBYTYPE_CAPTION, "Lists all used file types of the current project.", "", cmdBar, webMenu);

          CommandHelper.AddCommand(applicationObject, addInInstance, OLDEST_NAME, 2, OLDEST_CAPTION, "List the oldest 50 files.", "", cmdBar, webMenu);

          CommandHelper.AddCommand(applicationObject, addInInstance, NEWEST_NAME, 2, NEWEST_CAPTION, "List the 50 recently changed files.", "", cmdBar, webMenu);



          cmd = CommandHelper.AddCommand(applicationObject, addInInstance, FILEDIFF_NAME, 3, FILEDIFF_CAPTION, "Report the file differences.", "", cmdBar, diffMenu);

          // and add command to the contextmenu of files in solution explorer

          cmd.AddControl(vsBarItem, 3);

          cmd.AddControl(vsBarWebItem, 3);

          cmd.AddControl(vsBarMultiItem, 1);



          cmd = CommandHelper.AddCommand(applicationObject, addInInstance, MAKEPATCH_NAME, 7, MAKEPATCH_CAPTION, "Report the file differences in unified patch format.", "", cmdBar, diffMenu);

          // and add command to the contextmenu of files in solution explorer

          cmd.AddControl(vsBarItem, 4);

          cmd.AddControl(vsBarWebItem, 4);



          cmd = CommandHelper.AddCommand(applicationObject, addInInstance, FOLDERDIFF_NAME, 8, FOLDERDIFF_CAPTION, "Report the differences of 2 folders.", "", cmdBar, diffMenu);

          // and add command to the contextmenu of folders in solution explorer

          cmd.AddControl(vsBarFolder, 2);

          cmd.AddControl(vsBarWebFolder, 2);



          cmd = CommandHelper.AddCommand(applicationObject, addInInstance, EXPLORE_NAME, 4, EXPLORE_CAPTION, "Open this folder in the standard windows Explorer.", "");

          // and add command to the contextmenu of folders and projects in solution explorer

          cmd.AddControl(vsBarFolder, 3);

          cmd.AddControl(vsBarWebFolder, 3);

          cmd.AddControl(vsBarWebItem, 3);

          cmd.AddControl(vsBarProject, 10);

          cmd.AddControl(vsBarProjectNode, 11);



          cmd = CommandHelper.AddCommand(applicationObject, addInInstance, XSLT_NAME, 5, XSLT_CAPTION, "Transform a file using this xslt.", "", cmdBar, diffMenu);

          cmd.AddControl(vsBarItem, 5);

          cmd.AddControl(vsBarWebItem, 5);



          cmd = CommandHelper.AddCommand(applicationObject, addInInstance, BACKUP_NAME, 6, BACKUP_CAPTION, "Copy this file over to the backup folder.", "");

          // and add command to the contextmenu of files in solution explorer

          cmd.AddControl(vsBarItem, 6);

          cmd.AddControl(vsBarWebItem, 6);



          cmd = CommandHelper.AddCommand(applicationObject, addInInstance, OPTION_NAME, 6, OPTION_CAPTION, "Report or Set Options.", "");



        } catch (Exception ex) {

          System.Diagnostics.Debug.WriteLine(ex.Message, "OnConnection Exception");

        } // try

        isConnected = true;

      }

    } // OnConnection



    

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

      System.Diagnostics.Debug.Write(disconnectMode.ToString() + "\n", "OnDisconnection");



      if ((isConnected) && ((disconnectMode == ext_DisconnectMode.ext_dm_UserClosed))) {



        try {

          // Delete the Commands

          CommandHelper.RemoveCommand(applicationObject, COMMANDNAMESPACE + "." + EXPLORE_NAME);

          CommandHelper.RemoveCommand(applicationObject, COMMANDNAMESPACE + "." + BACKUP_NAME);

          CommandHelper.RemoveCommand(applicationObject, COMMANDNAMESPACE + "." + OPTION_NAME);



          CommandHelper.RemoveCommand(applicationObject, COMMANDNAMESPACE + "." + FILEDIFF_NAME);

          CommandHelper.RemoveCommand(applicationObject, COMMANDNAMESPACE + "." + MAKEPATCH_NAME);

          CommandHelper.RemoveCommand(applicationObject, COMMANDNAMESPACE + "." + FOLDERDIFF_NAME);

          CommandHelper.RemoveCommand(applicationObject, COMMANDNAMESPACE + "." + XSLT_NAME);



          CommandHelper.RemoveCommand(applicationObject, COMMANDNAMESPACE + "." + FILEBYTYPE_NAME);

          CommandHelper.RemoveCommand(applicationObject, COMMANDNAMESPACE + "." + OLDEST_NAME);

          CommandHelper.RemoveCommand(applicationObject, COMMANDNAMESPACE + "." + NEWEST_NAME);

          

          // Remove the controls from the CommandBars

          CommandHelper.RemoveCommandControl(applicationObject, "Item", FILEDIFF_CAPTION);

          CommandHelper.RemoveCommandControl(applicationObject, "Item", MAKEPATCH_CAPTION);

          CommandHelper.RemoveCommandControl(applicationObject, "Item", XSLT_CAPTION);

          CommandHelper.RemoveCommandControl(applicationObject, "Item", BACKUP_CAPTION);



          CommandHelper.RemoveCommandControl(applicationObject, "Folder", FOLDERDIFF_CAPTION);

          CommandHelper.RemoveCommandControl(applicationObject, "Folder", EXPLORE_CAPTION);



          CommandHelper.RemoveCommandControl(applicationObject, "Project", EXPLORE_CAPTION);

          CommandHelper.RemoveCommandControl(applicationObject, "Project Node", EXPLORE_CAPTION);



          ((CommandBars)(applicationObject.CommandBars))["Tools"].Controls[DIFFMENU].Delete(oMissing);

          ((CommandBars)(applicationObject.CommandBars))["Tools"].Controls[WEBTOOLSMENU].Delete(oMissing);



          if (registerCommandBar)

            applicationObject.Commands.RemoveCommandBar(((CommandBars)(applicationObject.CommandBars))[COMMANDBARNAME]);



          applicationObject = null;

          isConnected = false;



        } catch (Exception ex) {

          System.Diagnostics.Debug.WriteLine(ex.Message, "OnDisconnection Exception");

        } // try

      } // if

    } // OnDisconnection





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

      System.Diagnostics.Debug.WriteLine("called.", "OnAddInsUpdate");

      if (isConnected)

        CreateToolWindow();

    } // OnAddInsUpdate





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

      System.Diagnostics.Debug.WriteLine("called.", "OnStartupComplete");

      CreateToolWindow();



      // Define global options

      Options.DefineBoolOption(Options.SVNMODE, true);

      Options.DefineTextOption(Options.BASEVERSIONFOLDER, null);



      this.solutionEvents = applicationObject.Events.SolutionEvents;



      this.hOpened = new _dispSolutionEvents_OpenedEventHandler(SolutionEvents_Opened);

      this.solutionEvents.Opened += this.hOpened;



      this.hQueryCloseSolution = new _dispSolutionEvents_QueryCloseSolutionEventHandler(SolutionEvents_QueryCloseSolution);

      this.solutionEvents.QueryCloseSolution += this.hQueryCloseSolution;

    } // OnStartupComplete





    /// <summary>

    /// React when a solution is opened to load the settings. 

    /// </summary>

    private void SolutionEvents_Opened() {

      Options.LoadOptions(applicationObject);

    } // SolutionEvents_Opened





    /// <summary>

    /// React before a solution is closed to store the settings. 

    /// </summary>

    private void SolutionEvents_QueryCloseSolution(ref bool fCancel) {

      Options.SaveOptions(applicationObject);

      fCancel = false;

    } // SolutionEvents_QueryCloseSolution





    /// <summary>

    /// Create a new Tool Window, that will be used for displaying the output of the tools.

    /// </summary>

    private void CreateToolWindow() {

      object objTemp = null;



      if ((isConnected) && (applicationObject != null) && (windowToolWindow == null)) {

        try {

          windowToolWindow = applicationObject.Windows.CreateToolWindow(

            addInInstance, "{8856F961-340A-11D0-A96B-00C04FD705A2}",

            COMMANDBARNAME, "{CAFF8E86-0517-442B-9E00-E4C37419244C}", ref objTemp);



        } catch (Exception ex) {

          System.Diagnostics.Debug.WriteLine(ex.Message, "OnStartupComplete Exception");

        } // try



        // windowToolWindow.Visible = true;

        Browser = (SHDocVw.WebBrowser)objTemp;

        Browser.Navigate(@"about:blank", ref nullObj, ref nullObj, ref nullObj, ref nullObj);



        // attach event Handlers to the browser Window

        DWebBrowserEvents2_BeforeNavigate2EventHandler

          wbn = new DWebBrowserEvents2_BeforeNavigate2EventHandler(BrowserBeforeNavigate2);

        Browser.BeforeNavigate2 += wbn;



        // create an instance of every WebReport class to register the Options.

        new BackupFile();

        new ReportDiffFiles();

        new ReportDiffFolder();

        new MakePatchFile();

        new ReportFileTypes();

        new ReportNewest();

        new ReportOldest();

        new ReportXSLT();



      } // if

    } // CreateToolWindow





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

      // close the window.

      // VS.NET then remembers where it had been docked.

      windowToolWindow.Visible = false;

      windowToolWindow.Close(EnvDTE.vsSaveChanges.vsSaveChangesNo);



      if (this.hOpened != null)

        this.solutionEvents.Opened -= this.hOpened;

      if (this.hQueryCloseSolution != null)

        this.solutionEvents.QueryCloseSolution -= hQueryCloseSolution;



      this.hOpened = null;

      this.hQueryCloseSolution = null;

      this.solutionEvents = null;

    } // OnBeginShutdown





    /// <summary>Implements the QueryStatus method of the IDTCommandTarget interface. This is called when the command's availability is updated</summary>

    /// <param term='commandName'>The name of the command to determine state for.</param>

    /// <param term='neededText'>Text that is needed for the command.</param>

    /// <param term='status'>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 commandName, vsCommandStatusTextWanted neededText, ref vsCommandStatus status, ref object commandText) {



      if (neededText == EnvDTE.vsCommandStatusTextWanted.vsCommandStatusTextWantedNone) {



        if (commandName == COMMANDNAMESPACE + "." + FILEBYTYPE_NAME) {

          status = vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled;



        } else if (commandName == COMMANDNAMESPACE + "." + OLDEST_NAME) {

          status = vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled;



        } else if (commandName == COMMANDNAMESPACE + "." + NEWEST_NAME) {

          status = vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled;



        } else if (commandName == COMMANDNAMESPACE + "." + FILEDIFF_NAME) {

          status = vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled;



        } else if (commandName == COMMANDNAMESPACE + "." + MAKEPATCH_NAME) {

          status = vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled;



        } else if (commandName == COMMANDNAMESPACE + "." + XSLT_NAME) {

          status = vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled;



        } else if (commandName == COMMANDNAMESPACE + "." + FOLDERDIFF_NAME) {

          status = vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled;



        } else if (commandName == COMMANDNAMESPACE + "." + EXPLORE_NAME) {

          status = vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled;



        } else if (commandName == COMMANDNAMESPACE + "." + BACKUP_NAME) {

          status = vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled;



        } else if (commandName == COMMANDNAMESPACE + "." + OPTION_NAME) {

          status = vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled;



        } // if

      } // if

    } // QueryStatus





    /// <summary>Implements the Exec method of the IDTCommandTarget interface. This is called when the command is invoked.</summary>

    /// <param term='commandName'>The name of the command to execute.</param>

    /// <param term='executeOption'>Describes how the command should be run.</param>

    /// <param term='varIn'>Parameters passed from the caller to the command handler.</param>

    /// <param term='varOut'>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 commandName, vsCommandExecOption executeOption, ref object varIn, ref object varOut, ref bool handled) {

      handled = false;

      StringBuilder sb = null;

      StringWriter output = null;

      Report report = null;

      int ExpectedArgs = 0;

      string[] args = null;

      int argc = 0;



      if (executeOption == EnvDTE.vsCommandExecOption.vsCommandExecOptionDoDefault) {



        if ((applicationObject != null) && (Browser != null)) {

          System.Diagnostics.Debug.Write(commandName + "\n", "Exec");



          try {

            if (commandName == COMMANDNAMESPACE + "." + FILEBYTYPE_NAME) {

              report = new ReportFileTypes();



            } else if (commandName == COMMANDNAMESPACE + "." + NEWEST_NAME) {

              report = new ReportNewest();



            } else if (commandName == COMMANDNAMESPACE + "." + OLDEST_NAME) {

              report = new ReportOldest();



            } else if (commandName == COMMANDNAMESPACE + "." + FILEDIFF_NAME) {

              report = new ReportDiffFiles();



            } else if (commandName == COMMANDNAMESPACE + "." + MAKEPATCH_NAME) {

              report = new MakePatchFile();



            } else if (commandName == COMMANDNAMESPACE + "." + FOLDERDIFF_NAME) {

              report = new ReportDiffFolder();



            } else if (commandName == COMMANDNAMESPACE + "." + XSLT_NAME) {

              report = new ReportXSLT();



            } else if (commandName == COMMANDNAMESPACE + "." + EXPLORE_NAME) {

              ProjectItem p = (ProjectItem)applicationObject.SelectedItems.Item(1).ProjectItem;

              string fName;

              if (p != null) {

                fName = p.get_FileNames(0);

              } else {

                Project pro = applicationObject.SelectedItems.Item(1).Project;

                fName = pro.FullName;

                fName = fName.Substring(0, fName.LastIndexOf('\\'));

              } // if

              openExplorer(fName);



            } else if (commandName == COMMANDNAMESPACE + "." + BACKUP_NAME) {

              report = new BackupFile();



            } else if (commandName == COMMANDNAMESPACE + "." + OPTION_NAME) {

              report = new Options();

            } // if



            if (report != null) {

              ExpectedArgs = report.Arguments;

              StringCollection cmdArgs = new StringCollection();



              if (varIn != null) {

                Match m = Regex.Match((string)varIn, @"(('[^']*')|(""[^""]*"")|([^ ]+))\s*");

                while (m.Success) {

                  string arg = m.Groups[1].Value;

                  if ((arg[0] == '\'') || (arg[0] == '\"'))

                    arg = arg.Substring(1, arg.Length - 2);

                  cmdArgs.Add(arg);

                  m = m.NextMatch();

                } // while

              } // if



              // append default argument

              if (cmdArgs.Count < ExpectedArgs) {

                string s = report.DefaultArgument(applicationObject);

                if ((s != null) && (s.Length > 0))

                  cmdArgs.Add(s);

              } // if



              // append up to 2 selected project items

              if ((cmdArgs.Count < ExpectedArgs) && (applicationObject.SelectedItems.Count > 0)) {

                SelectedItem sel = applicationObject.SelectedItems.Item(1);

                cmdArgs.Add(GetSelFileName(sel));

              } // if



              if ((cmdArgs.Count < ExpectedArgs) && (applicationObject.SelectedItems.Count > 1)) {

                SelectedItem sel = applicationObject.SelectedItems.Item(2);

                cmdArgs.Add(GetSelFileName(sel));

              } // if



              // append default argument

              if (cmdArgs.Count < ExpectedArgs) {

                string s = report.AutoArgument(applicationObject, cmdArgs);

                if ((s != null) && (s.Length > 0))

                  cmdArgs.Add(s);

              } // if



              if (report.FolderParameter) {

                // request for folders

                while (cmdArgs.Count < ExpectedArgs) {

                  // request the folder path

                  FolderBrowserDialog fbd = new FolderBrowserDialog();

                  fbd.Description = String.Format("Select the {0}. folder parameter", cmdArgs.Count + 1);

                  if (argc > 0)

                    fbd.SelectedPath = args[0];

                  if (fbd.ShowDialog() == DialogResult.OK)

                    cmdArgs.Add(fbd.SelectedPath);

                  else

                    return; // do not execute this command on cancel.

                } // while



              } else {

                while (cmdArgs.Count < ExpectedArgs) {

                  // request the file path

                  OpenFileDialog ofd = new OpenFileDialog();

                  if (argc > 0)

                    ofd.InitialDirectory = args[0];

                  ofd.Filter = "All Files (*.*)|*.*";

                  ofd.RestoreDirectory = true;

                  ofd.Title = String.Format("Select the {0}. file", cmdArgs.Count + 1);

                  if (ofd.ShowDialog() == DialogResult.OK)

                    cmdArgs.Add(ofd.FileName);

                  else

                    return; // do not execute this command on cancel.

                } // while

              }

              // copy args to a plain array

              args = new string[cmdArgs.Count];

              cmdArgs.CopyTo(args, 0);



              // build text-version of the command and execute it through the command-Window.

              string cmdText = commandName;

              foreach (string c in args)

                cmdText += " '" + c + "'";



              // use the CommandWindow

              EnvDTE.Window win = applicationObject.Windows.Item(EnvDTE.Constants.vsWindowKindCommandWindow);

              EnvDTE.CommandWindow cmdWin = (EnvDTE.CommandWindow)win.Object;

              EnvDTE.TextDocument txt = cmdWin.TextDocument;



              // get last command in Command Window

              string lastCmdLine = txt.StartPoint.CreateEditPoint().GetText(txt.EndPoint);

              lastCmdLine = lastCmdLine.Replace("\r", "");

              string[] cmdLines = lastCmdLine.Split('\n');

              if ((cmdLines.Length > 1) && (cmdLines[cmdLines.Length - 1] == ">"))

                lastCmdLine = cmdLines[cmdLines.Length - 2].Substring(1);

              else if (cmdLines.Length > 0)

                lastCmdLine = cmdLines[cmdLines.Length - 1].Substring(1);

              else

                lastCmdLine = String.Empty;



              if (cmdText.ToLower().Replace("'", String.Empty).Replace("\"", String.Empty)

                == lastCmdLine.ToLower().Replace("'", String.Empty).Replace("\"", String.Empty)) {

                // execute this command

                LastCommand = cmdText.ToLower();



              } else if (cmdText.ToLower().Replace("'", String.Empty).Replace("\"", String.Empty)

                == LastCommand.ToLower().Replace("'", String.Empty).Replace("\"", String.Empty)) {

                // execute this command



              } else {

                // execute this command through the Command Window

                LastCommand = cmdText.ToLower();

                cmdWin.SendInput(cmdText, true);

                return; // this function will be called soon again - but with all parameters in the commandline.

              } // if



              // open the tool-window and start working...

              if (report.HasHTMLOutput) {

                windowToolWindow.Visible = true;

              } // if



              sb = new StringBuilder();

              output = new StringWriter(sb);

              if ((CommandStack.Count == 0) || (CommandStack[CommandStack.Count - 1] != LastCommand))

                CommandStack.Add(LastCommand);



              if (!report.HasHTMLOutput) {

                // just execute the command, no html output

                try {

                  report.Render(applicationObject, null, args);



                } catch (Exception ex) {

                  System.Windows.Forms.MessageBox.Show(ex.Message, COMMANDBARNAME);

                } // try



              } else {

                // Render the command to the HTML output window

                try {

                  report.Render(applicationObject, output, args);



                } catch (Exception ex) {

                  output.WriteLine("<html><body style='FONT-FAMILY: Arial,Verdana; FONT-SIZE: 9pt;'>");

                  output.WriteLine("<h3>{0} occured</h3>", ex.GetType().Name);

                  output.WriteLine("<p>{0}", ex.Message);

                  if (ex.HelpLink != null)

                    output.WriteLine("<br><br><a href='{0}'>Goto Error</a>", ex.HelpLink);

                  output.WriteLine("</p>");

                  output.WriteLine("</body></html>");

                } // try

              }



            } // if



          } catch (ArgumentException ae) {

            System.Windows.Forms.MessageBox.Show(ae.Message, COMMANDBARNAME);



          } catch (Exception) { } // try



          if (output != null) {

            output.Close();

            output = null;



            sb.Replace("[ROOT]", rootPath);



            // when the browser signals a load, it is not a refresh !

            IHTMLDocument2 hDoc2 = (IHTMLDocument2)Browser.Document;



            // clear the document first.

            hDoc2.write("");

            hDoc2.close();



            // write new content.

            hDoc2.write(sb.ToString());

            hDoc2.close();



            if (BrowserScrollTop > 0) {

              IHTMLElement2 html2= (IHTMLElement2)((IHTMLDocument3)Browser.Document).documentElement;

              html2.scrollTop = BrowserScrollTop;

              BrowserScrollTop = 0;

            } // if

          } // if



          handled = true;

          return;

        }

      }

    } // Exec



    /// <summary>Special method for getting the name of a selected item.

    /// VS.NET and the different projects are not consisted in this case.

    /// When the selected item is in a C# project it can be retrieved by using the index 0.

    /// When the selected item is in the  C# project it can be retrieved by using the index 0.</summary>

    /// <param name="sel">The selected item.</param>

    /// <returns>The full path and name of the selected file.</returns>

    private string GetSelFileName(SelectedItem sel) {

      string fileName = null;

      if (sel != null) {

        if (sel.ProjectItem.ContainingProject.Kind == "{66A2671D-8FB5-11D2-AA7E-00C04F688DDE}")

          fileName = sel.ProjectItem.get_FileNames(1);

        else

          fileName = sel.ProjectItem.get_FileNames(0);

      } // if

      return(fileName);

    } // GetSelFileName

  

    /// <summary>This method is attached to the browser event onbeforenavigate2 to capture dte: links</summary>

    /// <param name="ob1"></param>

    /// <param name="URL">The new url</param>

    /// <param name="Flags"></param>

    /// <param name="Name"></param>

    /// <param name="da"></param>

    /// <param name="Head"></param>

    /// <param name="Cancel">will set to true if a dte: command was found.</param>

    private void BrowserBeforeNavigate2(Object ob1, ref Object URL, ref Object Flags, ref Object Name, ref Object da, ref Object Head, ref bool Cancel) {

      int p;



      EnvDTE.Window win;



      if (URL != null) {

        string url = URL.ToString().ToLower();

        url = System.Web.HttpUtility.UrlDecode(url);



        System.Diagnostics.Debug.Write(url + "\n", "OnBeforeNav");



        if (url.ToLower().StartsWith("res://")) {

          // "sometimes" the ie reports a syntax error, but it is not... so reload the page

          System.Diagnostics.Debug.Write("OUPS!!!!\n", "OnBeforeNav");

          url = "dte:reload";

          Cancel = true;

          return;

        } // if



        if (url.ToLower() == "about:blank")

          url = "dte:reload"; // is a refresh !



        if (! url.ToLower().StartsWith("dte:")) {

          System.Windows.Forms.MessageBox.Show("catch:<" + url + ">", "OnBeforeNavigate2");



        } else {

          Cancel = true;



          // analyse http like url syntax

          StringDictionary urlParams = new StringDictionary();

          string urlPath;



          // analyse all the parameters

          p = url.IndexOf('?');

          if (p < 0) {

            urlPath = url;

          } else {

            urlPath = url.Substring(0, p);

            foreach (string s in url.Substring(p+1).Split('&')) {

              string [] param = s.Split('=');

              urlParams.Add(param[0].ToLower(), System.Web.HttpUtility.UrlDecode(param[1]));

            } // foreach

          } // if



          if (urlPath == "dte:file") {

            string fName = urlParams["file"];

            win = applicationObject.ItemOperations.OpenFile(fName, null);



            if (urlParams["line"] != null) {

              EnvDTE.TextSelection sel = (EnvDTE.TextSelection)win.Document.Selection;

              int fLine = int.Parse(urlParams["line"]);

              if (urlParams["pos"] == null) {

                // a line number is given

                sel.GotoLine(fLine, false);

              } else {

                int fPos = int.Parse(urlParams["pos"]);

                sel.MoveToLineAndOffset(fLine, fPos, false);

              } // if

            } // if



          } else if (urlPath == "dte:folder") {

            openExplorer(urlParams["folder"]);



          } else if (urlPath == "dte:back") {

            IHTMLElement2 html2= (IHTMLElement2)((IHTMLDocument3)Browser.Document).documentElement;

            BrowserScrollTop = html2.scrollTop;



            // go back one command and repeat it

            p = CommandStack.Count;

            if (p > 1) {

              LastCommand = CommandStack[p-2]; // do not record in the commandWindow

              CommandStack.RemoveAt(p-1);



              p = LastCommand.IndexOf(' ');

              if (p > 0) {

                applicationObject.ExecuteCommand(LastCommand.Substring(0, p), LastCommand.Substring(p+1));

              } else {

                applicationObject.ExecuteCommand(LastCommand, String.Empty);

              } // if

            } // if



          } else if (urlPath == "dte:reload") {

            IHTMLElement2 html2= (IHTMLElement2)((IHTMLDocument3)Browser.Document).documentElement;

            BrowserScrollTop = html2.scrollTop;



            // repeat last command. do not record in the commandWindow

            p = CommandStack.Count;

            if (p >= 1) {

              LastCommand = CommandStack[p-1];

              p = LastCommand.IndexOf(' ');

              if (p > 0) {

                applicationObject.ExecuteCommand(LastCommand.Substring(0, p), LastCommand.Substring(p+1));

              } else {

                applicationObject.ExecuteCommand(LastCommand, String.Empty);

              } // if

            } // if



          } else if (urlPath == "dte:diff") {

            string oldFile = urlParams["old"];

            string newFile = urlParams["new"];

            object param = "'" + newFile + "' '" + oldFile + "'";

            bool retBool = false;

            Exec(COMMANDNAMESPACE + "." + FILEDIFF_NAME, EnvDTE.vsCommandExecOption.vsCommandExecOptionDoDefault,

              ref param, ref nullObj, ref retBool);



          } else if (urlPath == "dte:difffolder") {

            string oldFile = urlParams["old"];

            string newFile = urlParams["new"];

            object param = "'" + newFile + "' '" + oldFile + "'";

            bool retBool = false;

            Exec(COMMANDNAMESPACE + "." + FOLDERDIFF_NAME, EnvDTE.vsCommandExecOption.vsCommandExecOptionDoDefault,

              ref param, ref nullObj, ref retBool);



          } else if (urlPath == "dte:transform") {

            string xmlFile = urlParams["xml"];

            string xsltFile = urlParams["xslt"];

            string html = urlParams["html"];



            string param = String.Format("'{0}' '{1}' {2}", xsltFile, xmlFile, 

              ((html == null) || (html.ToLower() != "true") ? String.Empty : "html"));



            applicationObject.ExecuteCommand(COMMANDNAMESPACE + "." + XSLT_NAME, param);

            

            // bool retBool = false;

            // Exec(COMMANDNAMESPACE + ".XSLTTransform", EnvDTE.vsCommandExecOption.vsCommandExecOptionDoDefault,

            //   ref param, ref nullObj, ref retBool);



          } else if (urlPath == "dte:copy") {

            IHTMLElement2 html2= (IHTMLElement2)((IHTMLDocument3)Browser.Document).documentElement;

            BrowserScrollTop = html2.scrollTop;



            string srcFile = urlParams["src"];

            string destFile = urlParams["dest"];



            ShellLib.ShellFileOperation.DeleteFile(destFile);

            File.Copy(srcFile, destFile, true);



            // repeat last command. do not record in the commandWindow

            p = CommandStack.Count;

            if (p >= 1) {

              LastCommand = CommandStack[p-1];

              p = LastCommand.IndexOf(' ');

              if (p > 0) {

                applicationObject.ExecuteCommand(LastCommand.Substring(0, p), LastCommand.Substring(p+1));

              } else {

                applicationObject.ExecuteCommand(LastCommand, String.Empty);

              } // if

            } // if



          } else if (urlPath == "dte:backup") {

            applicationObject.ExecuteCommand(COMMANDNAMESPACE + "." + BACKUP_NAME, "'" + urlParams["file"] + "'");



          } else {

            System.Windows.Forms.MessageBox.Show("catch:<" + url + ">", "OnBeforeNavigate2");

          } // if



        } // if

      } // if

    } // BrowserBeforeNavigate2





    /// <summary>Start the Explorer.</summary>

    /// <param name="folderName">The folder that should be shown fist.</param>

    private void openExplorer (string folderName) {

      System.Diagnostics.Process newProcess = new System.Diagnostics.Process();

      newProcess.StartInfo.FileName = folderName;

      newProcess.StartInfo.UseShellExecute = true;

      newProcess.StartInfo.ErrorDialog = true;

      newProcess.Start();

    } // openExplorer

  

  } // class

} // namespace

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect Deutsche Bank AG
Germany Germany
see https://www.mathertel.de

Comments and Discussions