可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I'm trying to create an add-in for SSMS 2008 and/or 2008 R2 but I've run into a problem straight away.
I can get my add-in to work and on SSMS start-up get it to simply show a message box.
However, after downloading various code-samples, when trying to reference Microsoft.SqlServer.Management.UI.VSIntegration.ServiceCache I get a null reference exception:
Commands2 commands = (Commands2)ServiceCache.ExtensibilityModel.Commands;
I get this problem when using SSMS 2008 or SSMS 2008 R2. I'm working on Visual Studio 2010.
It's a bit frustrating because I'm keen to learn more about SSMS add-ins but can't seem to get past the few samples out there.
Any advice/tips appreciated.
Thanks
回答1:
Karl, I don't know about your concrete problem here, but answering another question, I came across a bunch of articles and links on writing SSMS plug-ins - maybe one of them will be useful to you:
Some information can be found here:
- The Black Art of Writing a SQL Server Management Studio Add-In
- Building a SQL Server Management Studio Add-In
- Extend Functionality in SQL Server 2005 Management Studio with Add-ins
- SSMS Scripter - Internals, part 2 - plugging in
回答2:
ServiceCache is unreliable - from version to version it supports less and less and probable will go away at some point.
If you write SSMS Add-in, you can access internals by accessing VS ApplicationModel.
Something like that:
public void OnConnection(object application, ext_ConnectMode connectMode, object addInInst, ref Array custom)
{
_addInInstance = (AddIn)addInInst;
_applicationObject = _addInInstance.DTE as DTE2;
_applicationObject has Commands and other interesting stuff.
Please note, that application argument of OnConnection has an incorrect object passed in. That's why you have to use this line to get the right object: _applicationObject = _addInInstance.DTE as DTE2;
回答3:
I've been struggling with this for a while.
I've got an add-in what work in sql 2008 - written in VS2008.
I upgraded the project to VS2010 and started working on getting the sql 2008 r2 add-in working - I could not get this working for love nor money.
I tried lots of different things;
* deleting and re-adding all the references.
* changing the target framework.
Not a sausage.
Nothing worked....
Until I went back to VS2008 - I made the changes. (see Jonathan Kehayias blog: https://www.sqlskills.com/blogs/jonathan/sql-server-2012-extended-events-add-in-to-manage-2008r2-instances/)
Hurray for new versions!!
回答4:
Ok I find solution, the problem is between CLR2.0 and CLR 4.0
Source : http://blogs.msdn.com/b/mshneer/archive/2010/03/19/com-shim-wizards-for-vs-2010.aspx
Debugging add-ins targeting CLR 2.0 in
Visual Studio 2010
I had some problems debugging add-ins
if those were loading in CLR 2.0. I
would press F5, Excel would start up
and my add-in would run but the
breakpoints were not getting hit. So I
wanted to share what's going on and
how to set up your environment in such
a way that F5 experience is not
completely broken.
There is no magic in the way I usually
go about debugging the shared add-in -
either shimmed or unshimmed. I set a
breakpoint in the OnConnection method
in Connect.cs file, open project's
properties, go to the Debug section,
select the "Start External Program"
option and set the full path to my
Office application (e.g. "C:\Program
Files\Microsoft
Office\Office12\EXCEL.EXE"). Next I
right click on the project node in the
Solution Explorer and select "Set As
Startup Project". When I press F5 my
breakpoint is hit.
In Visual Studio 2010 the breakpoint
is not hit if my add-in is loaded in
CLR 2.0. What's going on is that
debugger cannot attach to both CLR 4.0
and CLR 2.0 - it actually needs to
know before the fact whether it should
be using CLR 2.0 debugging engine or
CLR 4.0 debugging engine. When you
press F5 debugger tries to guess which
CLR will be started in the process.
The heuristic is based on reading the
EXE's .config file where required
runtime version is u8sually specified
and if the .config file is not found
than the debugger fires up the CLR 4.0
debugging engine. As we all know
Office application are not bound to
any particular version of the CLR so
the heuristic miserably fails.
There are actually two ways of dealing
with it – one is to put an
.exe.config file alongside
the.exe itself e.g. when debugging
Excel 2007 I will create
Excel.exe.config and leave it in the
"C:\Program Files\Microsoft
Office\Office12" folder.
But my preferred way of dealing with
this is different. In the Solution
Explorer I will right click on my
solution node and select "Add" ->
"Existing Project" and open
"C:\Program Files\Microsoft
Office\Office12\EXCEL.EXE". Next, I
will right click on this newly added
project and select "Set As Startup
Project". Next, I will open the
properties for this project and will
set the "Debugger Type" property to
"Managed (v2.0, v1.1, v1.0)". Now, I
will F5 and the breakpoint I've set in
OnConnection method will be hit.
回答5:
I've the same problem. I think that it's liked to the Framework
With Framework 3.5
ServiceCache.ExtensibilityModel is not null
With Framework 4.0
"ServiceCache.ExtensibilityModel" is
null
回答6:
Ok, thanks for this way, but if I have a project in Framework 3.5, VS2010 doesn't stop on my break point.
But if I change the Framework to 4, VS2010 stop on the breakpoint. But CreateToolWindow2 raise an exception, because isn't the same Framework !
I simplify the code as minimum :
/// <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)
{
_addInInstance = (AddIn)addInInst;
_applicationObject = (DTE2)_addInInstance.DTE;
if (connectMode == ext_ConnectMode.ext_cm_Startup)//ext_ConnectMode.ext_cm_UISetup)
{
}
}
/// <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)
{
Windows2 win2 = this._applicationObject.Windows as Windows2;
if (win2 != null)
{
Assembly asm = Assembly.GetExecutingAssembly();
AddIn addinobj;
addinobj = this._applicationObject.AddIns.Item(1);
object controlObject = null;
Guid id = new Guid("4c410c93-d66b-495a-9de2-99d5bde4a3b9"); // this guid doesn't seem to matter?
//Window
Window windowTool = win2.CreateToolWindow2(addinobj,
asm.Location,
"MyAddinASupp.UserControl1", "Zone de test",
"{" + id.ToString() + "}",
ref controlObject);
windowTool.Visible = true;
}
}