Short post this one, but its something I needed to do during the course of developing a Visual Studio Add-In, so thought I’d note it down.

Along the way there were several test add-ins I developed as proofs-of-concept and to demonstrate that items could be added to different menus within the IDE. However, the Visual Studio IDE itself doesn’t appear to offer any easy way of removing add-ins once they have been integrated.

This is especially annoying when the IDE appears to lock the DLL for the particular plugin you are currently working on, preventing you from compiling any changes.

The ‘Add-in Manager’ (under Tools–>Add-in Manager) isn’t all that effective, and certainly doesn’t remove it. So what can we do?

Fortunately, there is an MSDN article to hand that explains exactly how to do this: How to: Deactivate and Remove an Add-In.

The steps (taken from this article) are as follows:

  1. Delete the .addin XML registration file for the add-in that you want to remove.

    The default location is ..\Users\username\ Documents\Visual Studio 2010\Addins\.

  2. At a Visual Studio command prompt, type devenv /resetaddin Namespace.ClassName, where Namespace is the name of your add-in project and Classname is its class name, for example, devenv /resetaddin MyAddin1.Connect.

Although this is very simple, it baffles me as to why there is not a simple option available in Visual Studio to do this.

Previous - Visual Studio Add Ins – Changing The Default Icon

, , ,

This is the second of a series of posts on Visual Studio Add-Ins that I’m writing to record my experiences on creating a plugin for Visual Studio.

Previously, we discussed Adding Items to Context Menus. On this occasion we are looking at how to customise the icon that is displayed.

VS Plugin Default Icon

As you can see from the above image, the default icon is an annoying little smiley face. When you search through the project, you find no reference to this icon, so you are left wondering how to change it.

Well, if you look at the OnConnection method in the Connect class you will see a call to AddNamedCommand2 located within the try/catch block.

The fifth and sixth parameters here are true and 59 by default. This stipulate that we are to use Windows default command bar button faces (true), and that we should use the 59th one (which happens to be a smiley face). Try changing this – you’ll get a different one.

Viewing all these button faces isn’t particularly easy. The MSDN Article Listing Button Faces in the Command Bar for the Microsoft Office System goes into a pretty lengthy explanation on how you might do this. However, we’re just interested in how we’re going to do this for ourselves.

Fortunately, there is another MSDN article How to: Display a Custom Icon on the Add-In Button that details just how to do this. There is little sense in reproducing this information here, so I suggest you follow the steps from the article. 

Tip: Read them all before you start the first one. Some of the steps don’t make any sense until later.

Previous -  Visual Studio Add-Ins – Adding Items to Context Menus.

Next -  Visual Studio Addins – Deactivate and Remove an Add-In.

, , ,

This is the first of a series of posts on Visual Studio Add-Ins, that I’m writing to record my experiences on creating a plugin for Visual Studio.

When developing a Visual Studio 2010 addin recently, I was wanting to add an item to the ‘Tools’ menu and to the context menu for the code-editor window.

This article is working from the assumption that you have already created the appropriate Visual Studio AddIns project. If not, you can do so by clicking File -> New Project -> Other Project Types -> Extensibility -> Visual Studio Add-in, and following the setup wizard.

The project you are given should add the menu items to the ‘Tools’ menu by default.

public void OnConnection(....
{
.....
    CommandBar menuBarCmds = ((CommandBars)_applicationObject.CommandBars)["MenuBar"];
    CommandBarControl toolsControl = menuBarCmds.Controls["Tools"];
    CommandBarPopup toolsPopup = (CommandBarPopup)toolsControl;
.....
    Command command = commands.Aon ddNamedCommand2(_addInInstance, ....
.....
    command.AddControl(toolsPopup.CommandBar, 1);

And to execute, we add our desired code to the Exec method later:

public void Exec(....
{
    ....
    if(commandName == "MyAddin1.Connect.MyAddin1") 
    {
        //your code here
    }

The code above adds a new option to the ‘Tools’ menu under ‘Menu Bar’. We are wanting to add specifically to the code editor context menu but are not sure which one it is.

I tracked this down rather unscientifically using the following process.

Firstly, add the following code to the OnConnection method:

CommandBars AllCommandBars = (CommandBars)_applicationObject.CommandBars;

We really want to inspect the contents of this object, and there is no better place than in debug mode. So, place a breakpoint upon this line and launch the app.

When the debugger hits the breakpoint you can step over the line (F10) and then inspect the contents:

As we can see there are 465 possible menus that we could add our item to. Which one? Well, it’s not “Code Window” as I originally anticipated. So how do we find this?

You may have a better method, but the way I found it was by trial and error.

I added the new menu item to all (465) menu controls in visual studio with the following loop

foreach (CommandBar cc in cmdBars)
{
    if (cc.Index >= 1 && cc.Index <= 465)
    {
        command.AddControl(cmdBars[cc.NameLocal]);
    }
}

I then narrowed this using a divide and conquer technique by adjusting the bounds of the loop:

if (cc.Index >= 1 && cc.Index <= 256)
    ...
    if (cc.Index >= 1 && cc.Index <= 128)
    ...
    if (cc.Index >= 64 && cc.Index <= 128)
    ...etc...

Until I eventually found what I was looking for.

The item in question lay at position [88] in the menu collection and was named “Script Context”. This means that the item will only appear when you are editing what Visual Studio deems as script files (this includes JavaScript).

Of worthy note (amongst others) are these other types of editor file:

  • HTML Context
  • ASPX Context
  • ASPX Code Context
  • ASPX VB Code Context

And now, when I right-click on the source of my JavaScript file, I can see the new menu that I have added.

Next - Visual Studio Add Ins – Changing The Default Icon

, , ,

I’ve been playing around with SSRS in SQL Server 2005 recently, and have been particularly encouraged by its potential as a central reporting tool. As part of this  I have been demonstrating how we can SSRS to produce reports from numerous different data sources and providers.

In this particular instance I have been testing its ability to produce reports from the output of an Oracle Package/Procedure and a SQL Server Stored Procedure.  Using the built-in .NET Client I was able to do this quite successfully with little fuss.

It was then brought to my attention that Microsoft are deprecating Oracle Client from ADO.NET 4. This means that, while the code may continue working for some considerable time, going forward it is a better strategy to use an alternative. So, I switched to using Oracle 11g Release 2 ODAC 11.2.0.1.2.

It’s worth noting that for those wanting to utilise an Oracle Stored procedure in SSRS, it must return its data in an OUT REF CURSOR. There are also a few other conditions which you must abide by.  For further info see: Tap into Oracle Databases with SQL Server Reporting Services.

Anyway, on to the problem…

So, as already intimated, all was fine and dandy, until I switched provider. I had set up the dataset on my report, entered the Stored Procedure name, and clicked ‘Ok’. Nothing happened; the IDE just hung.

At this point, I should probably reproduce the procedure in question:

PROCEDURE pck_mypackage.pr_myproc(L_CURSOR out SYS_REFCURSOR)
is
   BEGIN
     OPEN L_CURSOR FOR
       SELECT * FROM MyTable;
   END;

And here the connection string (missing the credentials).

Provider=OraOLEDB.Oracle.1;Data Source=DBSOURCE

Nothing shocking whatsoever, right?

For the first day or so, I took to killing Visual Studio, tweaking a few settings and then trying again. No-one in the websphere seemed to have encountered this; I was baffled. I even resorted to Window’s Process Monitor and trawling through the 1 million+ events it had logged.

So, I decided to confide in my old friend, the bullet-point list. I regaled it with the details of what was working, and what was not. Here it is, replete with the pertinent information:

What Works?

  • The stored procedure executes correctly in PL/SQL Developer
  • The ‘test connect’ in works fine in SSRS
  • A query string of SELECT * FROM MyTable; with Command Type of ‘text’ produces the correct fields in the SSRS report.
  • .NET Oracle Provider instead of Oracle OLE DB Provider

What Fails:

  • If i change the Command Type to ‘Stored Procedure’ and enter ‘pr_myproc’, when I click ‘OK’ Visual Studio 2005 (service pack 2) simply hangs/crashes.

My attention was drawn to the last three words, “simply hangs/crashes.” It was then I noticed that Visual Studio was not actually hanging completely. I could still click the top-right window buttons; it just seemed to be waiting.

I confided in a friendly DBA, who suggested I looked at the Oracle sessions in an attempt to determine:

  1. Whether or not a connection was actually being made, and,
  2. What it was doing if the connection was successful

Something must have piqued his interest, because he decided to do it there for me himself.

“Ahhh,” he said, “you’re querying sys.obj$.” He then proceeded to explain to me why exactly this was an issue. The schema we were searching had substantially large data dictionary. This dictionary has to be queried in order to bring back the procedure parameters and the REFCURSOR output.  When looking up the information, the two providers (.NET and Oracle) used two different queries that had a dramatic relative difference in their performances.

Here is the one the Oracle Provider used, taking 10+ minutes:

select * from (select null  PROCEDURE_CATALOG
                      , owner PROCEDURE_SCHEMA
                      , object_name PROCEDURE_NAME
                      , decode (object_type, 'PROCEDURE', 2, 'FUNCTION',  3, 1) PROCEDURE_TYPE
                      , null PROCEDURE_DEFINITION
                      , null DESCRIPTION
                      , created DATE_CREATED
                      , last_ddl_time DATE_MODIFIED
              from all_objects where object_type in ('PROCEDURE','FUNCTION')
              union all
              select null PROCEDURE_CATALOG
                          , arg.owner PROCEDURE_SCHEMA
                          , arg.package_name||'.'||arg.object_name PROCEDURE_NAME
                          , decode(min(arg.position), 0, 3, 2) PROCEDURE_TYPE
                          , null PROCEDURE_DEFINITION
                          , decode(arg.overload, '', '', 'OVERLOAD') DESCRIPTION
                          , min(obj.created) DATE_CREATED
                          , max(obj.last_ddl_time) DATE_MODIFIED
              from all_objects obj, all_arguments arg
              where arg.package_name is not null
              and   arg.owner = obj.owner
              and   arg.object_id = obj.object_id
              group by arg.owner, arg.package_name, arg.object_name, arg.overload ) PROCEDURES
WHERE PROCEDURE_NAME = 'pck_my_package.pr_myproc' order by 2, 3

The second SQL Statement in the union is a particular killer. Here, it joins all_objects and all_arguments tables! I actually ran this query in PL/SQL developer, but gave up after it failed to finish in thirty minutes.

This a particular problem of those schemas with large data dictionaries. I tried this in a smaller one, further up our shipping chain, and it returned in an acceptable amount of time.

, , , ,

Ever since installing Visual Studio 2010, I’ve been having a lot of fun trying to bend it to my will.

Dr. Evil
Image via Wikipedia

So far, I And have largely succeeded!

mwahahaha mwahahaha!!

My latest conquest was gained when attempting to humiliate VS2010 by getting it to debug an old Classic ASP website. It was then technological equivalent of a wealthy aristocrat being forced to wear the attire of a street beggar. You could almost picture the facial contortions amidst the snooty contempt that it must have felt in being asked to do such a task. To its credit, however, it did it with aplomb, and very little resistance.

Firstly, I should make it clear that I am making some assumptions. Namely, you have a Classic ASP website set up locally, you have a local version of IIS, and the website is under a virtual directory against this server.

So, what should we do?

  1. Open Visual Studio 2010
  2. This is easy enough if you have it installed. Might be a bit tricky if you don’t.

  3. Open your website in Visual Studio
  4. Again, easy enough.

  5. Fire up your web site.
  6. I.e. open your browser and navigate to the website.

  7. In Visual Studio, click ‘Debug’ Menu -> ‘Attach to process’
  8. You may need to tick the box labelled ‘Show processes from all users’
  9. Inetinfo.exe‘ if application protection is low or ”dllhost.exe‘ if application protection is higher. You may get an ‘Attach Security Warning’ popup. If so, continue On. It’s a bit scary at first, but if it’s your own app on your own PC, then you’ll be ok.

  10. If you’re worried about this, follow the advice on MSDN.

  11. Add a breakpoint to your code, and navigate to a location where you will hit it.

Troubleshooting - Registering pdm.dll

This worked on the first occasion that I tried it. Subsequent attempts were not so successful, and I found a few things that I had to do.

When trying to attach to ‘Script Code’ I got the following warning in the IDE.

Warning: Cannot debug script code. The correct version of pdm.dll is not registered. Repair your Visual Studio 2010 installation, or run ‘regsvr32.exe “%CommonProgramFiles%\Microsoft Shared\VS7Debug\pdm.dll”‘.

Just follow these instructions.

Troubleshooting - Restart IIS

This also helped on one occasion. Can’t really say why.


, , , ,

Right back from the days of Visual Studio 6, in the C++ IDE (not VB6 – it was different, and annoying), I’ve always found the ‘find in files’ option useful.

So, imagine my dismay, when I couldn’t find it in Visual Studio 2010.

Fortunately, I stumbled across a blog post by Thibaut Van Spaandonck who provided  idiot-proof step by step instructions on how to do this.

And, hurrah, it returned:

Thanks to you, Thibaut!

,