VS Add-In Error

Topics: Bugs
Feb 13, 2008 at 12:36 PM
I am using VS 2005 SP1, Windows XP SP2 and I have installed Sandcastle 2.4.10111 and DocProject 1.10.0. Everything is working fine, DocProject is executing correctly outside of VS. However, whenever I try to load the add-in in VS I get an error. The following is copied from the Application Event Log. Any ideas as to what is going wrong? Thanks

Event Type: Error
Event Source: DocProject
Event Category: None
Event ID: 0
Description:
An error occurred while initializing the DocProject Add-In.

System.ArgumentNullException: Value cannot be null.
Parameter name: parent
at DaveSexton.DocProject.MenuCommand..ctor(CommandBar parent, String name)
at DaveSexton.DocProject.MenuCommand..ctor(CommandBar parent, String name, Image image)
at DaveSexton.DocProject.MenuCommand..ctor(CommandBar parent, String name, Image image, Color imageTransparencyKey)
at DaveSexton.DocProject.DocProjectPropertiesMenuCommand..ctor()
at DaveSexton.DocProject.DocProjectPropertiesMenuCommand.get_Instance()
at DaveSexton.DocProject.DocProjectEnvironment.InitializeVSExtensions()
at DaveSexton.DocProject.DocProjectEnvironment.Initialize()
at DaveSexton.DocProject.DocProjectEnvironment.Initialize(IEnvironmentHost hostUI)
at DaveSexton.DocProject.DocProjectAddIn.Extensibility.IDTExtensibility2.OnStartupComplete(Array& custom)
Feb 13, 2008 at 4:13 PM
Hi,

Thanks for reporting this issue.

I checked the code and it appears that the cause of this problem is that the Project command bar doesn't exist in your copy of Visual Studio, or possibly that the one DocProject expects contains under 40 controls. Basically, DocProject iterates the entire DTE.CommandBars collection looking for a context menu named, Project with over 40 controls. It's possible that the number 40, which I chose based on testing a few different installations of VS, may be too high.

If you wouldn't mind running some diagnostic tests then maybe I'll be able to figure out a work-around for this particular situation.

Open Visual Studio's Macro IDE (Alt+F11) and add a new VB.NET module named, Commands. Paste in the following code:

''' Written by Dave Sexton 2007
Imports System
Imports EnvDTE
Imports EnvDTE80
Imports Microsoft.VisualStudio.CommandBars
Imports System.Diagnostics
 
Public Module Commands
    Public Sub ListAllCommands(Optional ByVal commandBarName As String = Nothing)
        Dim output As Output = output.GetWindow("Command List", clear:=True)
 
        If commandBarName Is Nothing Then
            For Each cmd As Command In DTE.Commands
                output.WriteLine(cmd.Name)
                System.Windows.Forms.Application.DoEvents()
            Next
        Else
            output.WriteLine("- All control names for the '" & commandBarName & "' command bar -")
 
            Try
                Dim bar As CommandBar = CType(DTE.CommandBars, CommandBars).Item(commandBarName)
 
                If Not bar Is Nothing Then
                    For Each control As CommandBarControl In bar.Controls
                        output.WriteLine("Control Name: " & control.Caption)
                    Next
                Else
                    output.WriteLine("Command bar not found.")
                End If
            Catch ex As Exception
            End Try
        End If
    End Sub
 
    Public Sub ListAllCommandBars(Optional ByVal caption As String = Nothing)
        Dim output As Output = output.GetWindow("Command List", clear:=True)
 
        If caption IsNot Nothing Then
            output.WriteLine("- Command bars that have a control with '" & caption & "' in the caption -")
 
            caption = caption.Trim()
        End If
 
        ' based on http://support.microsoft.com/kb/555154
 
        For Each bar As CommandBar In CType(DTE.CommandBars, CommandBars)
            If caption IsNot Nothing Then
                For Each control As CommandBarControl In bar.Controls
                    If control IsNot Nothing Then
                        Dim controlCaption As String = control.Caption
 
                        If (controlCaption Is Nothing) Then
                            controlCaption = ""
                        Else
                            controlCaption = controlCaption.Trim()
                        End If
 
                        If controlCaption.Contains(caption) OrElse caption.Contains(controlCaption) Then
                            output.WriteLine("Candidate CommandBar Name: {0}.           Matched control: {1}", _
                                bar.Name, controlCaption)
                            Exit For
                        End If
                    End If
                Next
            Else
                output.WriteLine(bar.Name)
                System.Windows.Forms.Application.DoEvents()
            End If
        Next
    End Sub
End Module
Create another module and name it, Output. Paste in the following code:

''' Written by Dave Sexton 2007
Imports System
Imports EnvDTE
Imports EnvDTE80
Imports System.Diagnostics
 
Public NotInheritable Class Output
    Public Shared Function GetWindow(ByVal Name As String, Optional ByVal show As Boolean = True, Optional ByVal clear As Boolean = False) As Output
        Dim window As Window
        Dim outputWindow As OutputWindow
        Dim outputWindowPane As OutputWindowPane
 
        window = DTE.Windows.Item(EnvDTE.Constants.vsWindowKindOutput)
        outputWindow = window.Object
 
        Try
            outputWindowPane = outputWindow.OutputWindowPanes.Item(Name)
        Catch e As System.Exception
            outputWindowPane = outputWindow.OutputWindowPanes.Add(Name)
        End Try
 
        If clear Then
            outputWindowPane.Clear()
        End If
 
        If show Then
            window.Visible = True
            outputWindowPane.Activate()
        End If
 
        Return New Output(outputWindowPane)
    End Function
 
    Public ReadOnly Property Pane() As OutputWindowPane
        Get
            Return _pane
        End Get
    End Property
    Private ReadOnly _pane As OutputWindowPane
 
    Public Sub New(ByVal _pane As OutputWindowPane)
        Me._pane = _pane
    End Sub
 
    Public Sub Write(ByVal text As String)
        _pane.OutputString(text)
    End Sub
 
    Public Sub Write(ByVal format As String, ByVal ParamArray args As Object())
        If (args Is Nothing) Then
            Write(format)
        Else
            _pane.OutputString(String.Format(format, args))
        End If
    End Sub
 
    Public Sub WriteLine()
        _pane.OutputString(Environment.NewLine)
    End Sub
 
    Public Sub WriteLine(ByVal text As String)
        _pane.OutputString(text & Environment.NewLine)
    End Sub
 
    Public Sub WriteLine(ByVal format As String, ByVal ParamArray args As Object())
        If (args Is Nothing) Then
            WriteLine(format)
        Else
            _pane.OutputString(String.Format(format, args) & Environment.NewLine)
        End If
    End Sub
End Class
  1. Close the Macros IDE.
  2. Open the Visual Studio command window (Alt+Ctrl+A).
  3. Type the following and press Enter: Macros.MyMacros.Commands.ListAllCommands Project
The output window should open up and you should see a list of all of the controls in the Project command bar. If the number of controls is under 40, then there's our problem.

Thanks,
Dave
Feb 13, 2008 at 4:56 PM
Macros.Samples.Commands.ListAllCommands Project

This gave me the following (39 controls):

- All control names for the 'Project' command bar -
Control Name: B&uild
Control Name: R&ebuild
Control Name: Depl&oy
Control Name: Clea&n
Control Name: Pro&ject Only
Control Name: Pu&blish...
Control Name: Run Code Analysis on Selection
Control Name: Convert to Web Application
Control Name: Check Accessi&bility...
Control Name: Project Dependencie&s...
Control Name: Project Bu&ild Order...
Control Name: A&dd
Control Name: Add &Reference...
Control Name: Add W&eb Reference...
Control Name: Add Service Reference...
Control Name: Add Test Script
Control Name: &View Class Diagram
Control Name: Set as St&artUp Project
Control Name: Debu&g
Control Name: &Add Solution to Source Control...
Control Name: Add S&elected Projects to Source Control...
Control Name: Chec&k Out for Edit...
Control Name: Check &In...
Control Name: View Pending C&heckins
Control Name: &Undo Checkout...
Control Name: Get &Latest Version (Recursive)
Control Name: &Get...
Control Name: View &History
Control Name: Cu&t
Control Name: &Paste
Control Name: &Delete
Control Name: Rena&me
Control Name: Re&load Project
Control Name: Un&load Project
Control Name: &Hide Folder
Control Name: U&nhide Folders
Control Name: C&hange Target Platform...
Control Name: Upgrade Projec&t
Control Name: P&roperties

Is there anything I can do to workaround this?

Thanks
Feb 13, 2008 at 5:33 PM
Hi,

Unfortunately, my assumption that 40 was fine, was wrong. Maybe 30, or even 20 would have been better. (I can only test a couple of copies of VS.)

The only way to fix this now is to rebuild the code. I'll copy this issue to a work item and have it fixed for the next release. In the mean time, if you want to rebuild the code yourself, the instructions are here: How To Use The Source Code. Ask if you need help.

What you need to do is change the hard-coded 40 to a 30 in the IsProjectContextMenu method of the DaveSexton.DocProject.DocProjectPropertiesMenuCommand class, which can be found in the DaveSexton.DocProject project.

Then rebuild. That should do the trick.

Note that rebuilding the DaveSexton.DocProject project will automatically re-GAC the assembly, so you won't have to uninstall/install DocProject to test the changes. Instead, just open another copy of Visual Studio.

If you try, please let me know if this solves the problem for you.

- Dave
Feb 13, 2008 at 5:34 PM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.