Macro that tests for proper implementation of AutomationProperties
Background:
VSPackages can offer up a set of custom properties for their Tools.Options pages, by registering the pages under Visual Studio's AutomationProperties registry key, by using the ProvideOptionPageAttribute. This allows for programmatic access to the Tools.Options properties via DTE.Properties( <categoryName> , <pageName> ).
The Example.OptionsPage sample in the Visual Studio SDK is missing the following attributes on its DialogPage derived objects.
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.AutoDual)]
Unfortunately, this mistake has been copied by many package partners (including internal teams here at Microsoft). Consequently, we occasionally see customers running into problems attempting to programmatically access Tools.Options properties with the above mentioned DTE.Properties interface.
Solution:
To help address this oft made mistake, Paul Harrington and Doug Hodges recently wrote the following macro which tests all VSPackages registered under AutomationProperties, to see which objects are implemented properly, and which are not. If you have a VSPackage that adds pages to the Tools.Options dialog, you may also which to add this macro to your arsenal of testing tools.
Imports Microsoft.Win32
Sub TestAutomationProperties()
Dim properties As EnvDTE.Properties
Dim ow As OutputWindow = DTE.ToolWindows.OutputWindow
Dim op As OutputWindowPane = ow.OutputWindowPanes.Add("Test Automation Properties")
op.Activate()
op.Clear()
Dim regrootKey As RegistryKey = Registry.LocalMachine.OpenSubKey(DTE.RegistryRoot, False)
Dim automationPropertiesKey As RegistryKey = regrootKey.OpenSubKey("AutomationProperties", False)
Dim categoryName As
String
For
Each categoryName In automationPropertiesKey.GetSubKeyNames
Dim categoryKey As RegistryKey = automationPropertiesKey.OpenSubKey(categoryName, False)
For
Each pageName As
String
In categoryKey.GetSubKeyNames
Dim pageKey As RegistryKey = categoryKey.OpenSubKey(pageName, False)
Try
properties = DTE.Properties(categoryName, pageName)
If properties.Count = 0 Then
op.OutputString("*** BUG: " + categoryName + "." + pageName + " must add [ClassInterface(ClassInterfaceType.AutoDual)] attribute" + vbCrLf)
Else
op.OutputString(categoryName + "." + pageName + " has " + properties.Count.ToString() + " properties" + vbCrLf)
End
If
Catch ex As Exception
op.OutputString("*** BUG: " + categoryName + "." + pageName + " must add [ComVisible(true)] attribute" + vbCrLf)
End
Try
Next
Next
End
Sub
Caveats:
While adding the [ClassInterface(ClassInterfaceType.AutoDual)] attribute allows you to expose the DialogPage's properties through the DTE.Properties method, it exposes 'all' public properties, including those from your base classes, such as the "Site", "AutomationObject" and "Container" properties, and others hidden from the Import/Export Settings feature (through the use of the DesignerSerializationVisibilityAttribute).
However, the development team is currently working to address this in VS 2010, and alleviate the need to use the ClassInterface attribute to expose the dialogs properties.