MZTools Articles Series: PRB: Performance problem of DTE.CommandBars[name] for CommandbarPopups in Visual Studio 2010

While not recommended because there can be two different  commandbar popups with the same name, you could use DTE.CommandBars[commandBarPopupName] to retrieve the commandbar of a CommandbarPopup from the DTE.CommandBars collection. However, the new WPF-based commandbars of Visual Studio 2010 introduce a performance problem when doing it so if the commandbar popup has not been displayed in the Visual Studio user interface.

This new article exposes the problem and provides proper ways to retrieve a commandbar popup:

PRB: Performance problem of DTE.CommandBars[name] for CommandbarPopups in Visual Studio 2010
http://www.mztools.com/articles/2011/MZ2011005.aspx

MZ-Tools Articles Series: BUG: EnvDTE80.CodeEvent.Comment doesn’t return “” for C# events without doc comment

This article documents a small bug of the Visual Studio code model:

BUG: EnvDTE80.CodeEvent.Comment doesn’t return “” for C# events without doc comment
http://www.mztools.com/articles/2011/MZ2011007.aspx

The bug report that I filed to Microsoft Connect is here:

https://connect.microsoft.com/VisualStudio/feedback/details/652387/envdte80-codeevent-comment-returns-doc-doc-instead-of-for-c-events-without-doc-comment#details

MSDN Community Content for “Automation and Extensibility for Visual Studio” updated for VS 2010

I mentioned in my last post that the MSDN documentation for Visual Studio uses a mechanism in the URL to reference several versions of Visual Studio. I noticed that the Community Content at the bottom of each documentation page doesn’t propagate from one documentation version to the next one, with good criteria I guess because maybe the content is not relevant in the next version. So, although long overdue too, I have entered today the community content for MSDN VS 2010 documentation that I entered in Sep 2008 for Visual Studio 2008 since all of it is relevant. It has been dozens of blocks with references to articles of the MZ-Tools Article Series.

MZ-Tools Resources about Visual Studio .NET extensibility updated for VS 2010

MSDN has a nice URL mechanism to reference several Visual Studio versions of the same documentation, for example:

Automation and Extensibility for Visual Studio (Visual Studio 2010)
http://msdn2.microsoft.com/en-us/library/xc52cke4(en-US,VS.100).aspx

Automation and Extensibility for Visual Studio (Visual Studio 2008)
http://msdn2.microsoft.com/en-us/library/xc52cke4(en-US,VS.90).aspx

Automation and Extensibility for Visual Studio (Visual Studio 2005)
http://msdn2.microsoft.com/en-us/library/xc52cke4(en-US,VS.80).aspx

Long overdue, but today I have updated the MZ-Tools Resources about Visual Studio .NET extensibility page with links to Visual Studio 2010 extensibility resources (downloads of SDKs, documentation, etc.).

Visual Studio 2010 Productivity Power Tools crashing when add-in calls Application.DoEvents

I had three bug reports from customers of my MZ-Tools add-in for Visual Studio 2010 with a “System.NullReferenceException: Object reference not set to an instance of an object.” that happened “when closing Visual Studio”. The stack trace is something like this:

System.NullReferenceException: Object reference not set to an instance of an object.
   at Microsoft.VisualStudio.Text.Editor.Implementation.DefaultScrollMap.TranslatePosition(SnapshotPoint bufferPosition)
   at Microsoft.VisualStudio.Text.Editor.Implementation.DefaultScrollMap.GetCoordinateAtBufferPosition(SnapshotPoint bufferPosition)
   at Microsoft.PowerTools.OverviewMargin.Implementation.OverviewMargin.SimpleScrollBar.GetYCoordinateOfBufferPosition(SnapshotPoint bufferPosition)
   at Microsoft.PowerTools.CaretMargin.CaretMarginElement.InvalidateIfChanged(Boolean highlightsChanged)
   at Microsoft.PowerTools.CaretMargin.CaretMarginElement.<UpdateMarginMatches>b__1(Object )
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
   at System.Windows.Threading.DispatcherOperation.InvokeImpl()
   at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)
   at System.Threading.ExecutionContext.runTryCode(Object userData)
   at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Windows.Threading.DispatcherOperation.Invoke()
   at System.Windows.Threading.Dispatcher.ProcessQueue()
   at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
   at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
   at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
   at System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 uReason, Int32 pvLoopData)
   at System.Windows.Forms.ComponentManagerProxy.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
   at System.Windows.Forms.Application.DoEvents()
   …

And indeed my add-in calls Application.DoEvents() in the event handler that sets to get notified when a solution is closed (that’s why the exception can happen “when closing Visual Studio”). I patched my add-in to ignore that exception, but the other day I got that exception too when calling DoEvents in other parts of the add-in, so it seems that any call to Application.DoEvents() can cause that exception in the Visual Studio 2010 Productivity Power Tools. I am using the latest version 10.0.20318.14 at the time of this writing.

Uninstalling Visual Studio 2010 SP1

Today finally I decided to uninstall SP1 of Visual Studio 2010. A sad decision, because I like to have the latest service packs and hotfixes, but my definition of service pack is something that fixes bugs, not introducing new ones, and SP1 introduces these two issues (a bug and a “by design” change actually) that I can’t stand anymore, and that are not going to be fixed:

VS 2010 SP1 breaks add-in debugging targetting .NET Framework 2.0 rather than .NET Framework
https://www.visualstudioextensibility.com/2011/03/15/vs-2010-sp1-breaks-add-in-debugging-targetting-net-framework-2-0-rather-than-net-framework

VS 2010 SP1 changing “ByVal” VB.NET code editor experience
https://www.visualstudioextensibility.com/2011/03/15/vs-2010-sp1-changing-quot-byval-quot-vb-net-code-editor-experience

I guessed that uninstalling SP1 from my laptop and my desktop computers was going to be long, and certainly it was so. Furthermore, it was annoying because the uninstaller asks for the original installation sources, even the installation source of Visual Studio 2010 Express Edition for one specific component (which I think never was installed on the computer that prompted for them, the other didn’t). Not only uninstalling SP1 is a long procedure (not unattended due to the source installation prompts) , but also you must reinstall or repair Visual Studio after uninstalling SP1. All of these are known issues described in the readme of Visual Studio 2010 SP1:

Visual Studio SP1 Readme:
http://go.microsoft.com/fwlink/?LinkId=210711

After a couple of (wasted) hours, I think that both Visual Studio 2010 installations are working again, without SP1.

More on VS 2010 SP1 breaks add-in debugging targetting .NET Framework 2.0

Sergey Vlasov, from Tabs Studio, has found a workaround to the problem of VS 2010 SP1 breaks add-in debugging targetting .NET Framework 2.0 that I posted yesterday:

Debugging add-ins for Tabs Studio in VS 2010 SP1
http://blog.tabsstudio.com/2011/03/16/debugging-add-ins-for-tabs-studio-in-vs-2010-sp1/

Thanks, Sergey.

On the other hand, apparently this problem debugging add-ins targeting something below .NET Framework 4.0 can also happen without SP1 according to this report in the MSDN VXS Forum (although the reports refers to a shared add-in for Office, not an add-in for Visual Studio 2010)

VS 2010 SP1 changing “ByVal” VB.NET code editor experience

Apart from these ones, other thing that I dislike a lot of SP1 of Visual Studio is that it has changed the editing experience of “ByVal” in the VB.NET code editor.

While in “classic” VB6 “ByRef” was the default and “ByVal” was required to pass parameters by value, in VB.NET it’s the opposite: “ByVal” is the default and “ByRef” is required to pass parameters by reference. However, until VS 2010 SP1, the VB.NET code editor always added “ByVal” when typing or when generating code (like in the parameters of event handlers).

My first alarm sign was reading:

Visual Basic Editor

in the Description of Visual Studio 2010 Service Pack 1. And indeed, after installing SP1, “ByVal” was not inserted when typing parameters in VB.NET. I tried to find some setting in the Options window to get back the old behavior, to no avail. I e-mailed the program managers who changed this behavior, which in turn introduced me the developer, and they confirmed that there is no setting (and no plans) to get the old behavior in the VB.NET code editor. So, after applying SP1:

1) If you like the old style, you have to type “ByVal” on your own.

2) Likely you will end with inconsistent styles in your VB.NET code, sometimes using “ByVal” (old code) and sometimes missing it (new code).

These irreversible changes of behavior is not what I expect from a service pack (I expect it to fix bugs, not to introduce issues). This should deserve a setting (opt-in) for those people who want to get rid of “ByVal”, and let the people who want the old behavior as they are.

VS 2010 SP1 breaks add-in debugging targetting .NET Framework 2.0 rather than .NET Framework

I installed the Service Pack 1 (SP1) of Visual Studio 2010 last week and in a few hours I was already unhappy with it.

I use VS 2010 to develop my MZ-Tools add-in and since it targets VS 2005, VS 2008 and VS 2010 with a single binary add-in dll, the add-in project uses .NET Framework 2.0 and CLR 2.0 (the only one supported by VS 2005), not .NET Framework 4.0 with CLR 4.0. Soon after installing VS 2010 I noticed that breakpoints were not hit when debugging the add-in!

I created a new minimal add-in with the wizard and debugging worked. Then I tried to change the .NET Framework of the add-in project from 4.0 to 2.0, and the debugging stopped working. I reproduced it on two computers with SP1 applied to VS 2010, so I reported it to Microsoft:

VS 2010 SP1 breaks add-in debugging targetting .NET Framework 2.0 rather than .NET Framework 4.0
https://connect.microsoft.com/VisualStudio/feedback/details/650694/vs-2010-sp1-breaks-add-in-debugging-targetting-net-framework-2-0-rather-than-net-framework-4-0#details

And I am not the only one affected by this issue.

When I read the list of fixes of a service pack of any product, it seems that it never fixes my bugs :-(. VS 2010 SP1 doesn’t fix a random crash that I experience deleting lines in VB.NET code, and due to the previous problem I can’t test if it fixes the Performance problem (100% CPU) for long time deattaching VS 2010 after debugging an add-in that happens with VS 2010 but not with VS 2008, and according to Microsoft, not with the next version of Visual Studio.

But at least I expect that a SP doesn’t break something. This was not the case with VS 2010 SP1.

MZ-Tools Articles Series: HOWTO: Get a CommandBar by Guid and Id rather than by name from a Visual Studio add-in

Getting a Visual Studio built-in commandbar to add buttons to it is not so easy as it may seem. You have the DTE.CommandBars collection, but:

– To retrieve a commandbar by name, you have to guess its name first. See: HOWTO: Guessing the name of a command bar to add a custom menu entry in Visual Studio .NET add-ins

– If the commandbar is not a “root” commandbar, but a commandbar popup, it may not be indexed in that collection, so it is better to get it from the parent CommandBar.Controls collection, but it is not so easy. See: HOWTO: Locate commandbars in international versions of Visual Studio

– Some command bar names are dupplicated.

There is other way to get a commandbar, using its Guid and Id that are truly unique. But this has also some tricks as explained in my latest article:

HOWTO: Get a CommandBar by Guid and Id rather than by name from a Visual Studio add-in
http://www.mztools.com/articles/2011/MZ2011004.aspx

VS SDK, packages, add-ins, macros and more…