天天看點

C# VC VB.NET JS 注釋小插件(外接程式)

在上一個項目中由于修改代碼 裡面的添加/删除/修改的注釋都有規範,是以做了一個注釋的第三方dll小插件。效果不錯,被日本Nes要去全面推廣讓其他協力公司都用。

是以提取出來發給大家。先上代碼。在Vs2012裡面。我試了下沒成功,是以先發代碼。稍後我整合打包傳上來了。

VS 建立外接程式 參考連結

http://technet.microsoft.com/zh-tw/library/90855k9f

http://technet.microsoft.com/zh-cn/library/ms165621

http://technet.microsoft.com/zh-cn/library/7k3w6w59

http://www.cnblogs.com/Reborn/archive/2010/02/04/1664010.html C#利用外接程式生成解決方案

http://technet.microsoft.com/zh-cn/magazine/ms228771%28VS.90%29.aspx  如何:在外接程式按鈕上顯示自定義圖示

Connect.cs 最重要的類。注釋的方法都在裡面

/// <summary>用于實作外接程式的對象。</summary>
    public class Connect : IDTExtensibility2, IDTCommandTarget
    {
        /// <summary>實作外接程式對象的構造函數。請将您的初始化代碼置于此方法内。</summary>
        public Connect()
        {
        }

        ///  <summary>實作 IDTExtensibility2 接口的 OnConnection 方法。接收正在加載外接程式的通知。</summary>
        /// <param term='application'>宿主應用程式的根對象。</param>
        /// <param term='connectMode'>描述外接程式的加載方式。</param>
        /// <param term='addInInst'>表示此外接程式的對象。</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 == ext_ConnectMode.ext_cm_UISetup)
            {
                object[] contextGUIDS = new object[] { };
                Commands2 commands = (Commands2)_applicationObject.Commands;
                string toolsMenuName;
                try
                {
                    //  添加在菜單欄裡面
                    //  CommandBar.resx.
                    ResourceManager resourceManager = new ResourceManager("StarkingCommentTool.CommandBar", Assembly.GetExecutingAssembly());
                    CultureInfo cultureInfo = new System.Globalization.CultureInfo(_applicationObject.LocaleID);
                    string resourceName = String.Concat(cultureInfo.TwoLetterISOLanguageName, "Tools");
                    toolsMenuName = resourceManager.GetString(resourceName);
                }
                catch
                {
                    toolsMenuName = "Tools";
                }

                //将此指令置于“工具”菜單上。
                //查找 MenuBar 指令欄,該指令欄是容納所有主菜單項的頂級指令欄:
                Microsoft.VisualStudio.CommandBars.CommandBar menuBarCommandBar = ((Microsoft.VisualStudio.CommandBars.CommandBars)_applicationObject.CommandBars)["MenuBar"];

                //在 MenuBar 指令欄上查找“工具”指令欄:
                CommandBarControl toolsControl = menuBarCommandBar.Controls[toolsMenuName];
                CommandBarPopup toolsPopup = (CommandBarPopup)toolsControl;

                //如果希望添加多個由您的外接程式處理的指令,可以重複此 try/catch 塊,
                //  隻需確定更新 QueryStatus/Exec 方法,使其包含新的指令名。
                try
                {
                    //将一個指令添加到 Commands 集合:
                    Command commandA = commands.AddNamedCommand2(_addInInstance, "Add", "Add", "Add Comment", true, 59, ref contextGUIDS, (int)vsCommandStatus.vsCommandStatusSupported + (int)vsCommandStatus.vsCommandStatusEnabled, (int)vsCommandStyle.vsCommandStylePictAndText, vsCommandControlType.vsCommandControlTypeButton);
                    Command commandD = commands.AddNamedCommand2(_addInInstance, "Del", "Del", "Delete Comment", true, 59, ref contextGUIDS, (int)vsCommandStatus.vsCommandStatusSupported + (int)vsCommandStatus.vsCommandStatusEnabled, (int)vsCommandStyle.vsCommandStylePictAndText, vsCommandControlType.vsCommandControlTypeButton);
                    Command commandC = commands.AddNamedCommand2(_addInInstance, "Chg", "Chg", "Change Comment", true, 59, ref contextGUIDS, (int)vsCommandStatus.vsCommandStatusSupported + (int)vsCommandStatus.vsCommandStatusEnabled, (int)vsCommandStyle.vsCommandStylePictAndText, vsCommandControlType.vsCommandControlTypeButton);

                    //将對應于該指令的控件添加到“工具”菜單:
                    if ((commandA != null) && (commandD != null) && (commandC != null) && (toolsPopup != null))
                    {
                        commandA.AddControl(toolsPopup.CommandBar, 1);
                        commandD.AddControl(toolsPopup.CommandBar, 1);
                        commandC.AddControl(toolsPopup.CommandBar, 1);
                    }
                }
                catch (System.ArgumentException)
                {
                    //如果出現此異常,原因很可能是由于具有該名稱的指令
                    //  已存在。如果确實如此,則無需重新建立此指令,并且
                    //  可以放心忽略此異常。
                }
            }
        }
        /// <summary>實作 IDTExtensibility2 接口的 OnDisconnection 方法。接收正在解除安裝外接程式的通知。</summary>
        /// <param term='disconnectMode'>描述外接程式的解除安裝方式。</param>
        /// <param term='custom'>特定于宿主應用程式的參數數組。</param>
        /// <seealso class='IDTExtensibility2' />
        public void OnDisconnection(ext_DisconnectMode disconnectMode, ref Array custom)
        {
        }

        /// <summary>實作 IDTExtensibility2 接口的 OnAddInsUpdate 方法。當外接程式集合已發生更改時接收通知。</summary>
        /// <param term='custom'>特定于宿主應用程式的參數數組。</param>
        /// <seealso class='IDTExtensibility2' />		
        public void OnAddInsUpdate(ref Array custom)
        {
        }

        /// <summary>實作 IDTExtensibility2 接口的 OnStartupComplete 方法。接收宿主應用程式已完成加載的通知。</summary>
        /// <param term='custom'>特定于宿主應用程式的參數數組。</param>
        /// <seealso class='IDTExtensibility2' />
        public void OnStartupComplete(ref Array custom)
        {
            ReadConf();
        }

        /// <summary>實作 IDTExtensibility2 接口的 OnBeginShutdown 方法。接收正在解除安裝宿主應用程式的通知。</summary>
        /// <param term='custom'>特定于宿主應用程式的參數數組。</param>
        /// <seealso class='IDTExtensibility2' />
        public void OnBeginShutdown(ref Array custom)
        {
        }

        /// <summary>實作 IDTCommandTarget 接口的 QueryStatus 方法。此方法在更新該指令的可用性時調用</summary>
        /// <param term='commandName'>要确定其狀态的指令的名稱。</param>
        /// <param term='neededText'>該指令所需的文本。</param>
        /// <param term='status'>該指令在使用者界面中的狀态。</param>
        /// <param term='commandText'>neededText 參數所要求的文本。</param>
        /// <seealso class='Exec' />
        public void QueryStatus(string commandName, vsCommandStatusTextWanted neededText, ref vsCommandStatus status, ref object commandText)
        {
            if (neededText == vsCommandStatusTextWanted.vsCommandStatusTextWantedNone)
            {
                switch (commandName)
                {
                    case "StarkingCommentTool.Connect.Add":
                        goto case "StarkingCommentTool.Connect.Chg";
                    case "StarkingCommentTool.Connect.Del":
                        goto case "StarkingCommentTool.Connect.Chg";
                    case "StarkingCommentTool.Connect.Chg":
                        status = (vsCommandStatus)vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled;
                        return;
                }
            }
        }
        private DTE2 _applicationObject;
        private AddIn _addInInstance;
        private string _add1 = "";//before add
        private string _add2 = "";//after add
        private string _del1 = "";//before del
        private string _del2 = "";//after del
        private string _changeBefore1 = "";//change before
        private string _changeAfter2 = "";//change after
        private string _changeDel = "";// comment ///
        private bool _autoCopy = true;//複制

        private void ReadConf()
        {
            try
            {
                string strPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\Visual Studio 2012\Addins\StarkingCommentTool.conf";

                string strUserName = Environment.UserName;
                string strDateFormat = "yyyy.MM.dd";

                string strAddFormatA = "NES Add {0} {1}";
                string strAddFormatB = "NES Add {0} {1}";

                string strDelFormatA = "NES Del {0} {1}";
                string strDelFormatB = "NES Del {0} {1}";

                string strCgAFormatB = "NES Change After {0} {1}";

                string strCgBFormatA = "NES Change Before {0} {1}";
                string strAllA = "";
                string strAllB = "";

                string strAddA = "";
                string strAddB = "";

                string strDelA = "";
                string strDelB = "";

                string strCgAB = "";

                string strCgBA = "";

                string strComm = "";

                if (!File.Exists(strPath))
                {
                    System.Windows.Forms.MessageBox.Show("Starking_comment_tool can't read config file \rplease check it exist!", "Starking_comment_tool Error");
                }
                else
                {
                    XmlDocument xd = new XmlDocument();
                    xd.Load(strPath);
                    XmlNode root = xd.ChildNodes[1];
                    //取出XML配置檔案裡面的自定義内容
                    strAddFormatA = root.SelectSingleNode("/config/before/add").InnerText;

                    strDelFormatA = root.SelectSingleNode("/config/before/del").InnerText;

                    strCgBFormatA = root.SelectSingleNode("/config/before/changeBefore").InnerText;

                    strAddFormatB = root.SelectSingleNode("/config/after/add").InnerText;

                    strDelFormatB = root.SelectSingleNode("/config/after/del").InnerText;

                    strCgAFormatB = root.SelectSingleNode("/config/after/changeAfter").InnerText;

                    strComm = root.SelectSingleNode("/config/comment").InnerText + " ";
                    _changeDel = strComm;

                    strDateFormat = root.SelectSingleNode("/config/dateFormat").InnerText + " ";
                    //
                    //取出XML配置檔案節點other裡面的自定義内容
                    strAllA = root.SelectSingleNode("/config/other/before/all").InnerText;
                    strAddA = root.SelectSingleNode("/config/other/before/add").InnerText;
                    strDelA = root.SelectSingleNode("/config/other/before/del").InnerText;

                    strCgBA = root.SelectSingleNode("/config/other/before/changeBefore").InnerText;

                    strAllB = root.SelectSingleNode("/config/other/after/all").InnerText;
                    strAddB = root.SelectSingleNode("/config/other/after/add").InnerText;
                    strDelB = root.SelectSingleNode("/config/other/after/del").InnerText;
                    strCgAB = root.SelectSingleNode("/config/other/after/changeAfter").InnerText;


                    string strAutoCopy = root.SelectSingleNode("/config/changeAutoCopy").InnerText;
                    bool.TryParse(strAutoCopy, out _autoCopy);
                }

                string strDate = DateTime.Now.ToString(strDateFormat);
                //add
                _add1 = strComm + string.Format(strAddFormatA, strDate, strUserName) + strAddA + strAllA + Environment.NewLine;

                _add2 = strComm + string.Format(strAddFormatB, strDate, strUserName) + strAddB + strAllB + Environment.NewLine;

                //change
                _changeBefore1 = strComm + string.Format(strCgBFormatA, strDate, strUserName) + strCgBA + strAllA + Environment.NewLine;

                _changeAfter2 = strComm + string.Format(strCgAFormatB, strDate, strUserName) + strCgAB + strAllB + Environment.NewLine;

                //delete
                _del1 = strComm + string.Format(strDelFormatA, strDate, strUserName) + strDelA + strAllA + Environment.NewLine;
                _del2 = strComm + string.Format(strDelFormatB, strDate, strUserName) + strDelB + strAllB + Environment.NewLine;

            }
            catch (Exception ex)
            {
                System.Windows.Forms.MessageBox.Show(ex.Message);
            }
        }
        /// <summary>實作 IDTCommandTarget 接口的 Exec 方法。此方法在調用該指令時調用。</summary>
        /// <param term='commandName'>要執行的指令的名稱。</param>
        /// <param term='executeOption'>描述該指令應如何運作。</param>
        /// <param term='varIn'>從調用方傳遞到指令處理程式的參數。</param>
        /// <param term='varOut'>從指令處理程式傳遞到調用方的參數。</param>
        /// <param term='handled'>通知調用方此指令是否已被處理。</param>
        /// <seealso class='Exec' />
        public void Exec(string commandName, vsCommandExecOption executeOption, ref object varIn, ref object varOut, ref bool handled)
        {
            handled = false;
            if (executeOption == vsCommandExecOption.vsCommandExecOptionDoDefault)
            {
                switch (commandName)
                {
                    #region//StarkingCommentTool.Connect.Add
                    case "StarkingCommentTool.Connect.Add":
                        TextSelection ts = _applicationObject.ActiveDocument.Selection as TextSelection;
                        int TopLine = ts.TopPoint.Line;
                        int ButtomLine = ts.BottomPoint.Line;
                        bool ButtomAtStartOfLine = ts.BottomPoint.AtStartOfLine;
                        int startLine = 0;
                        int endLine = 0;

                        if (TopLine == ButtomLine)
                        {
                            ts.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstColumn, false);
                            ts.Insert(_add1, 0);
                            ts.SmartFormat();
                            ts.LineDown(false, 1);
                            ts.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstColumn, false);
                            ts.Insert(_add2, 0);
                            ts.SmartFormat();
                            ts.GotoLine(TopLine + 2, false);
                        }
                        else
                        {

                            if (ts.TopPoint.AtEndOfLine)
                            {
                                ts.GotoLine(TopLine + 1, false);
                                ts.Insert(_add1, 0);
                            }
                            else
                            {
                                ts.GotoLine(TopLine, false);
                                ts.Insert(_add1, 0);
                            }
                            ts.SmartFormat();

                            if (ButtomAtStartOfLine)
                            {
                                ts.GotoLine(ButtomLine + 1, false);
                                ts.Insert(_add2, 0);
                            }
                            else
                            {
                                ts.GotoLine(ButtomLine + 2, false);
                                ts.Insert(_add2, 0);
                            }

                            ts.SmartFormat();
                        }

                        handled = true;
                        return;
                    #endregion

                    #region//StarkingCommentTool.Connect.Del
                    case "StarkingCommentTool.Connect.Del":
                        ts = _applicationObject.ActiveDocument.Selection as TextSelection;
                        TopLine = ts.TopPoint.Line;
                        ButtomLine = ts.BottomPoint.Line;
                        ButtomAtStartOfLine = ts.BottomPoint.AtStartOfLine;

                        // Area Delete
                        if (ts.TopPoint.AtEndOfLine)
                        {
                            ts.GotoLine(TopLine + 1, false);
                            startLine = TopLine + 2;
                            ts.Insert(_del1, 0);
                        }
                        else
                        {
                            ts.GotoLine(TopLine, false);
                            startLine = TopLine + 1;
                            ts.Insert(_del1, 0);
                        }
                        if (ButtomAtStartOfLine)
                        {
                            ts.GotoLine(ButtomLine + 1, false);
                            endLine = ButtomLine;
                            ts.Insert(_del2, 0);
                        }
                        else
                        {
                            ts.GotoLine(ButtomLine + 2, false);
                            endLine = ButtomLine + 1;
                            ts.Insert(_del2, 0);
                        }
                        for (int line = startLine; line < endLine + 1; line++)
                        {
                            ts.GotoLine(line, false);
                            ts.SelectLine();
                            if (ts.Text.Contains("	") || ts.Text.Contains("{") || ts.Text.Contains("}") || ts.Text.Contains("//") || !ts.Text.Contains("///") || !ts.Text.Contains("#region") || !ts.Text.Contains("#endregion"))
                            {
                                ts.Insert(ts.Text.TrimStart("	".ToCharArray()), 0);
                            }
                            if (ts.Text.Contains(" ") || ts.Text.Contains("{") || ts.Text.Contains("}") || ts.Text.Contains("//") || !ts.Text.Contains("///") || !ts.Text.Contains("#region") || !ts.Text.Contains("#endregion"))
                            {
                                ts.Insert(_changeDel + ts.Text.TrimStart(" ".ToCharArray()), 0);
                            }
                        }
                        //縮放注釋到多少列 start==>end
                        ts.GotoLine(TopLine, false);
                        //計算選中的行數來進行注釋
                        if (TopLine == ButtomLine)
                        {   //單行删除注釋
                            ts.LineDown(true, ButtomLine + 3 - TopLine);
                        }
                        else
                        {   //多行删除注釋
                            ts.LineDown(true, ButtomLine + (endLine + 1 - startLine) - TopLine);
                        }
                        ts.SmartFormat();

                        handled = true;
                        return;
                    #endregion

                    #region//StarkingCommentTool.Connect.Chg
                    case "StarkingCommentTool.Connect.Chg":
                        ts = _applicationObject.ActiveDocument.Selection as TextSelection;
                        TopLine = ts.TopPoint.Line;
                        ButtomLine = ts.BottomPoint.Line;
                        ButtomAtStartOfLine = ts.BottomPoint.AtStartOfLine;
                        int intCount = ts.TextRanges.Count;
                        if (TopLine == ButtomLine)//單行變更
                        {
                            ts.GotoLine(TopLine, false);
                            ts.SelectLine();
                            //選中要變化的内容
                            string strText = string.Empty;
                            if (ts.Text.Contains("	") || ts.Text.Contains("{") || ts.Text.Contains("}") || ts.Text.Contains("//") || !ts.Text.Contains("///") || !ts.Text.Contains("#region") || !ts.Text.Contains("#endregion"))
                            {
                                strText = ts.Text.TrimStart("	".ToCharArray());
                            }
                            if (ts.Text.Contains(" ") || ts.Text.Contains("{") || ts.Text.Contains("}") || ts.Text.Contains("//") || !ts.Text.Contains("///") || !ts.Text.Contains("#region") || !ts.Text.Contains("#endregion"))
                            {
                                strText = ts.Text.TrimStart(" ".ToCharArray());
                            }
                            string strText2 = _changeBefore1 + _changeDel + strText.Replace("	", "");
                            //複制要變更的内容
                            if (_autoCopy)
                                strText2 += strText;
                            else
                                strText2 += Environment.NewLine;
                            strText2 += _changeAfter2;
                            //插入變更内容
                            ts.Insert(strText2, 0);
                            ts.GotoLine(TopLine, false);
                            //單行删除注釋
                            ts.LineDown(true, ButtomLine + 4 - TopLine);
                            ts.SmartFormat();
                        }
                        else//多行内容變更
                        {
                            if (!ts.TopPoint.AtEndOfLine && !ButtomAtStartOfLine)
                            {
                                intCount++;
                            }
                            if (ts.TopPoint.AtEndOfLine)
                            {
                                ts.GotoLine(TopLine + 1, false);
                                startLine = TopLine + 2;
                                ts.Insert(_changeBefore1, 0);
                            }
                            else
                            {
                                ts.GotoLine(TopLine, false);
                                startLine = TopLine + 1;
                                ts.Insert(_changeBefore1, 0);
                            }
                            if (ButtomAtStartOfLine)
                            {
                                ts.GotoLine(ButtomLine + 1, false);
                                endLine = ButtomLine;
                            }
                            else
                            {
                                ts.GotoLine(ButtomLine + 2, false);
                                endLine = ButtomLine + 1;
                            }
                            //存放選中變化的内容
                            StringBuilder sb = new StringBuilder();
                            if (_autoCopy)
                            {
                                for (int line = startLine; line < endLine + 1; line++)
                                {
                                    ts.GotoLine(line, false);
                                    ts.SelectLine();
                                    sb.Append(ts.Text);
                                }
                            }
                            //循環注釋掉選中的内容
                            for (int line = startLine; line < endLine + 1; line++)
                            {
                                ts.GotoLine(line, false);
                                ts.SelectLine();
                                if (ts.Text.Contains("	") || ts.Text.Contains("{") || ts.Text.Contains("}") || ts.Text.Contains("//") || !ts.Text.Contains("///") || !ts.Text.Contains("#region") || !ts.Text.Contains("#endregion"))
                                {
                                    ts.Insert(ts.Text.TrimStart("	".ToCharArray()), 0);
                                }
                                if (ts.Text.Contains(" ") || ts.Text.Contains("{") || ts.Text.Contains("}") || ts.Text.Contains("//") || !ts.Text.Contains("///") || !ts.Text.Contains("#region") || !ts.Text.Contains("#endregion"))
                                {
                                    ts.Insert(_changeDel + ts.Text.TrimStart(" ".ToCharArray()), 0);
                                }
                            }
                            //複制選中的内容到計算好的行數中
                            ts.GotoLine(endLine + 1, false);
                            if (_autoCopy)
                            {
                                ts.Insert(sb.ToString(), 0);
                                ts.GotoLine(endLine + intCount, false);
                            }
                            else
                            {
                                ts.NewLine(1);
                            }
                            //插入注釋結束語句
                            ts.Insert(_changeAfter2, 0);
                            ts.GotoLine(TopLine, false);
                            //計算行數光标停止在最後一行+1行
                            ts.LineDown(true, (endLine + intCount + 1) - TopLine);
                            ts.SmartFormat();
                        }
                        handled = true;
                        return;
                    #endregion
                }
            }
        }
    }
           

StarkingCommentTool.AddIn 建立自動産生的裡面放外接程式的資訊

<?xml version="1.0" encoding="UTF-16" standalone="no"?>
<Extensibility xmlns="http://schemas.microsoft.com/AutomationExtensibility">
  <HostApplication>
    <Name>Microsoft Visual Studio</Name>
    <Version>11.0</Version>
  </HostApplication>
	<Addin>
		<FriendlyName>StarkingCommentTool</FriendlyName>
		<Description>C# VC VB.NET JS 注釋工具</Description>
		<Assembly>StarkingCommentTool.dll</Assembly>
		<FullClassName>StarkingCommentTool.Connect</FullClassName>
		<LoadBehavior>5</LoadBehavior>
		<CommandPreload>1</CommandPreload>
		<CommandLineSafe>1</CommandLineSafe>
	</Addin>
</Extensibility>
           

StarkingCommentTool.conf  配置檔案 你可以配置成自己想要的注釋風格

<?xml version="1.0" encoding="utf-8" ?>
<config>
    <!--
  add: 追加
  del: 削除
  changeAfter: 変更前
  changeBefore: 変更後
  {0}: 時間格式化
  NOTE: 請不要删除此檔案中的注釋(重要都是配置節點)
  -->
    <before>
        <!-- 変更前的應用 -->
        <add>{0}1處System對應 INSERT START</add>
        <del>{0}1處System對應 DELETE START</del>
        <changeBefore>{0}1處System對應 UPDATE START</changeBefore>
    </before>

    <after>
        <!-- 変更後的應用 -->
        <add>{0}1處System對應 INSERT END</add>
        <del>{0}1處System對應 DELETE END</del>
        <changeAfter>{0}1處System對應 UPDATE END</changeAfter>
    </after>
   
    <!--   dateFormat:日期格式化
     例:
      日付 2012年12月25日 
      dateFormat: yyyy.MM.dd
      注釋中的格式為中 2012.12.25 。
  -->
    <dateFormat>yy/MM/dd</dateFormat>
    <other>
        <!-- 
  all: 追加,削除,変更前,変更後等最後要追加的文字。
  add: 追加後最後要追加的文字。
  del: 削除後最後要追加的文字。
  changeAfter: 修改前最後要追加的文字。
  changeBefore: 修改後変最後要追加的文字。
  
  all的優先級是最低的
  例如 other中, 如果添加了all和add的場合, 那麼注釋中就會顯示other.add other.all的樣子。
    -->
        <before>
            <all></all>
            <add></add>
            <del></del>
            <changeBefore></changeBefore>
        </before>

        <after>
            <all></all>
            <add></add>
            <del></del>
            <changeAfter></changeAfter>
        </after>
    </other>

    <!-- 修改的内容是否複制-->
    <changeAutoCopy>True</changeAutoCopy>

    <!-- 注釋 
       VB: ' 
       C#: ///
   -->
    <comment>///</comment>
</config>
           

先貼出代碼,稍後我整理測試完畢打包上傳。