SSMS可扩展性项目 - 如何研究/调试

时间:2013-02-26 02:11:45

标签: c# extensibility ssms-2012 ssms-addin

关于创建SSMS扩展的this answer静脉:

namespace SSMSAddin
{
    using System;
    using System.IO;
    using Extensibility;
    using EnvDTE;
    using EnvDTE80;
    using Microsoft.VisualStudio.CommandBars;
    using Microsoft.SqlServer.Management.UI.VSIntegration;
    using System.Windows.Forms;

    public class Connect : IDTExtensibility2, IDTCommandTarget
    {
        private DTE2 applicationObject;
        private CommandEvents executeSqlEvents;
        private AddIn addInInstance;

        public Connect() { }

        public void OnConnection(object application, ext_ConnectMode connectMode, object addInInst, ref Array custom)
        {
            this.applicationObject = (DTE2)application;
            this.addInInstance = (AddIn)addInInst;

            this.applicationObject = (DTE2)application;
            this.executeSqlEvents = this.applicationObject.Events.CommandEvents["{52692960-56BC-4989-B5D3-94C47A513E8D}", 1];
            this.executeSqlEvents.BeforeExecute += this.ExecuteSqlEventsBeforeExecute;

            if (connectMode == ext_ConnectMode.ext_cm_UISetup)
            {
                var contextGUIDS = new object[] { };
                var commands = (Commands2)this.applicationObject.Commands;
                string toolsMenuName = "Tools";

                //Place the command on the tools menu.
                //Find the MenuBar command bar, which is the top-level command bar holding all the main menu items:
                CommandBar menuBarCommandBar = ((CommandBars)this.applicationObject.CommandBars)["MenuBar"];

                //Find the Tools command bar on the MenuBar command bar:
                CommandBarControl toolsControl = menuBarCommandBar.Controls[toolsMenuName];
                CommandBarPopup toolsPopup = (CommandBarPopup)toolsControl;

                //This try/catch block can be duplicated if you wish to add multiple commands to be handled by your Add-in,
                //  just make sure you also update the QueryStatus/Exec method to include the new command names.
                try
                {
                    //Add a command to the Commands collection:
                    Command command = commands.AddNamedCommand2(this.addInInstance, "SSMSAddin", "SSMSAddin", "Executes the command for SSMSAddin", true, 59, ref contextGUIDS, (int)vsCommandStatus.vsCommandStatusSupported + (int)vsCommandStatus.vsCommandStatusEnabled, (int)vsCommandStyle.vsCommandStylePictAndText, vsCommandControlType.vsCommandControlTypeButton);

                    //Add a control for the command to the tools menu:
                    if ((command != null) && (toolsPopup != null))
                    {
                        command.AddControl(toolsPopup.CommandBar, 1);
                    }
                }
                catch (ArgumentException)
                {
                    //If we are here, then the exception is probably because a command with that name
                    //  already exists. If so there is no need to recreate the command and we can 
                    //  safely ignore the exception.
                }
            }
        }

        private void ExecuteSqlEventsBeforeExecute(string guid, int id, object customin, object customout, ref bool canceldefault)
        {
            try
            {
                Document document = ((DTE2)ServiceCache.ExtensibilityModel).ActiveDocument;
                var textDocument = (TextDocument)document.Object("TextDocument");

                string queryText = textDocument.Selection.Text;

                if (string.IsNullOrEmpty(queryText))
                {
                    EditPoint startPoint = textDocument.StartPoint.CreateEditPoint();
                    queryText = startPoint.GetText(textDocument.EndPoint);
                }

                DateTime now = DateTime.Now;
                // string server = 
                string folderPath = string.Format(@"B:\SSMS Queries\{0}", now.ToString("yyyyMMdd"));
                string fileName = now.ToString("yyyyMMdd-HHmmss") + ".sql";
                Directory.CreateDirectory(folderPath);
                string fullPath = Path.Combine(folderPath, fileName);
                File.WriteAllText(fullPath, queryText);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        public void OnDisconnection(ext_DisconnectMode disconnectMode, ref Array custom) { }

        public void OnAddInsUpdate(ref Array custom) { }

        public void OnStartupComplete(ref Array custom) { }

        public void OnBeginShutdown(ref Array custom) { }

        public void QueryStatus(string commandName, vsCommandStatusTextWanted neededText, ref vsCommandStatus status, ref object commandText)
        {
            if (neededText == vsCommandStatusTextWanted.vsCommandStatusTextWantedNone)
            {
                if (commandName == "SSMSAddin.Connect.SSMSAddin")
                {
                    status = (vsCommandStatus)vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled;
                    return;
                }
            }
        }

        public void Exec(string commandName, vsCommandExecOption executeOption, ref object varIn, ref object varOut, ref bool handled)
        {
            handled = false;
            if (executeOption == vsCommandExecOption.vsCommandExecOptionDoDefault)
            {
                if (commandName == "SSMSAddin.Connect.SSMSAddin")
                {
                    var document = ((DTE2)ServiceCache.ExtensibilityModel).ActiveDocument;
                    if (document != null)
                    {
                        //replace currently selected text
                        var selection = (TextSelection)document.Selection;
                        selection.Insert(
@"Welcome to SSMS. This sample is brought to you by

SSMSBoost add-in team

Check www.ssmsboost.com for updates.",
(Int32)EnvDTE.vsInsertFlags.vsInsertFlagsContainNewText);
                    }

                    handled = true;
                    return;
                }
            }
        }
    }
}

代码添加了一个在SSMS 2012中的每个SQL Execute之前触发的事件...我点击F5,sql查询运行,但在运行之前它将查询的副本保存到B:\SSMS Queries\20130225\083000.sql

这有什么缺失?我想为使用的Connection / Databse添加选项,例如B:\SSMS Queries\Localhost\Northwind\20130225\083000.sql(仅举例)。

我通常会做什么......断点,单步执行,检查对象等......这是一个插件。类库。你不能断点/跨步库......

如何将断点放入加载到SSMS / Visual Studio中的类库中以便我可以研究?或者什么是这种修补的好资源? object customin, object customout中的某个地方是我想要修改的信息。

2 个答案:

答案 0 :(得分:1)

问题的第二部分,找到与当前数据库的连接..

添加对Microsoft.SqlServer.RegSrvrEnum.dll和SqlWorkBench.Interfaces的引用(位于C:\ ProgramFiles .. \ SQL Server .. - 中的某处)。确保您已为工具安装了SDK。

然后下面的代码就可以了(欢迎你!)

IScriptFactory scriptFactory = ServiceCache.ScriptFactory;
CurrentlyActiveWndConnectionInfo connectionIfno = scriptFactory.CurrentlyActiveWndConnectionInfo;
UIConnectionInfo conn = connectionIfno.UIConnectionInfo;
Debug.WriteLine("{0}::{1}", conn.ServerName, conn.AdvancedOptions["DATABASE"]);

答案 1 :(得分:0)

实际记录我的答案(忘记多次后)。在SSMSBoostTSQLTidy.Blogspot(以及Martin Smith评论)

的组合中找到了我的答案
1) Set SSMS as the startup project inside Debug Profile. File location for SSMS2012:
    C:\Program Files (x86)\Microsoft SQL Server\110\Tools\Binn\ManagementStudio\SSMS.exe
2) I've created 2 Addin files:
    MyAddin.Debug.Addin
    MyAddin.Release.Addin
    (Contents updated as listed below)
3) Add postbuild event to create directory if not exists
4) Add postbuild event to copy Addin from ProjectDir to MSeventShared
5) Turn off P-Invoke warnings. Press CRLT + ALT + E - In Managed Debugging Assistants, find PInvokeStackImbalance, untick it.

Addin Files(Release将DLL位置从Project目录更改为MSEnvShared \ Admin文件夹):

<?xml version="1.0" encoding="UTF-16" standalone="no"?>
<Extensibility xmlns="http://schemas.microsoft.com/AutomationExtensibility">
    <HostApplication>
        <Name>Microsoft SQL Server Management Studio</Name>
        <Version>*</Version>
    </HostApplication>
    <Addin>
        <FriendlyName>MyAddin.</FriendlyName>
        <Description>MyAddin Description.</Description>
        <Assembly>C:\Projects\MyAddin\bin\Debug\MyAddin.dll</Assembly>
        <FullClassName>SSMSAddin.Connect</FullClassName>
        <LoadBehavior>0</LoadBehavior>
    <CommandPreload>1</CommandPreload>
    <CommandLineSafe>0</CommandLineSafe>
     </Addin>
</Extensibility>

构建后活动:

cmd /x /c mkdir "C:\ProgramData\Microsoft\MSEnvShared\Addins\"
cmd /C copy "$(ProjectDir)MyAddin.$(ConfigurationName).Addin" "C:\C:\ProgramData\Microsoft\MSEnvShared\Addins\MyAddin.Addin"