I thought I already posted a blog entry about my last article:
BUG: SolutionBuild.Build method builds only one project in Visual Studio add-ins or macros
http://www.mztools.com/articles/2008/MZ2008002.aspx
but it seems that no, so there it is. Today I was adding another post with more info:
Someone posted a question about this in the MSDN forums and I suggested to try the interfaces of the SDK (such as IVsSolutionBuildManager) instead of the automation model (EnvDTE). I have had a little time to actually try it and, alas, it doesn’t work too, so it seems that the bug happens in the service and not in the automation model. If you load the add-in for a solution with two projects, you will notice that only the startup project is actually built, the same problem that using the automation model. If this bug is important for you, vote for it on the Microsoft Connect web site:
http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=320688
As you will notice, the bug was opened three times, somehow MS failed to reproduce it twice and close it, and when finally they reproduced it their explanation is that if you have the Tools, Options, Projects and Solutions, Build and Run, “Only build startup projects and dependencies on Run” option set to True, then SolutionBuild should honor it. This is absurd, because nobody is talking about “Run” here, we are talking about “Build”, which is a different thing. If I ask programmatically SolutionBuild.Build, I would expect the whole solution to be built…
The workaround is to iterate all the projectsof the solution (taking into account the dependencies, I guess) and build each one individually, this is insane…
Below is the code using the SDK just in case you are interested.
Imports System
Imports Microsoft.VisualStudio.CommandBars
Imports Extensibility
Imports EnvDTE
Imports EnvDTE80
Imports System.Runtime.InteropServices
Imports Microsoft.VisualStudio.Shell.Interop
Public Class Connect
Implements IDTExtensibility2
<ComVisible(True), ComImport(), Guid("6D5140C1-7436-11CE-8034-00AA006009FA"), _
InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)> _
Friend Interface IServiceProvider
<PreserveSig()> _
Function QueryService(<InAttribute()> ByRef guidService As Guid, _
<InAttribute()> ByRef riid As Guid, <OutAttribute()> ByRef ppvObject As IntPtr) As Integer
End Interface
Private m_objDTE2 As DTE2
Public Sub OnConnection(ByVal application As Object, ByVal connectMode As ext_ConnectMode, ByVal addInInst As Object, ByRef custom As Array) Implements IDTExtensibility2.OnConnection
m_objDTE2 = CType(application, DTE2)
Select Case connectMode
Case ext_ConnectMode.ext_cm_Startup
' OnStartupComplete will be called automatically
Case ext_ConnectMode.ext_cm_AfterStartup
OnStartupComplete(Nothing)
End Select
End Sub
Public Sub OnStartupComplete(ByRef custom As Array) Implements IDTExtensibility2.OnStartupComplete
BuildSolution()
End Sub
Private Sub BuildSolution()
Dim objIVsSolutionBuildManager As IVsSolutionBuildManager
Dim iResult As Integer
objIVsSolutionBuildManager = DirectCast(GetService(m_objDTE2, GetType(IVsSolutionBuildManager)), IVsSolutionBuildManager)
iResult = objIVsSolutionBuildManager.StartSimpleUpdateSolutionConfiguration(CType(VSSOLNBUILDUPDATEFLAGS.SBF_OPERATION_BUILD Or VSSOLNBUILDUPDATEFLAGS.SBF_OPERATION_FORCE_UPDATE, UInt32), 0, 0)
End Sub
Friend Function GetService(ByVal serviceProvider As Object, ByVal type As System.Type) As Object
Return GetService(serviceProvider, type.GUID)
End Function
Friend Function GetService(ByVal serviceProvider As Object, ByVal guid As System.Guid) As Object
Dim objService As Object = Nothing
Dim objIServiceProvider As IServiceProvider
Dim objIntPtr As IntPtr
Dim hr As Integer
Dim objSIDGuid As Guid
Dim objIIDGuid As Guid
objSIDGuid = guid
objIIDGuid = objSIDGuid
objIServiceProvider = CType(serviceProvider, IServiceProvider)
hr = objIServiceProvider.QueryService(objSIDGuid, objIIDGuid, objIntPtr)
If hr <> 0 Then
System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(hr)
ElseIf Not objIntPtr.Equals(IntPtr.Zero) Then
objService = System.Runtime.InteropServices.Marshal.GetObjectForIUnknown(objIntPtr)
System.Runtime.InteropServices.Marshal.Release(objIntPtr)
End If
Return objService
End Function
Public Sub OnDisconnection(ByVal disconnectMode As ext_DisconnectMode, ByRef custom As Array) Implements IDTExtensibility2.OnDisconnection
End Sub
Public Sub OnAddInsUpdate(ByRef custom As Array) Implements IDTExtensibility2.OnAddInsUpdate
End Sub
Public Sub OnBeginShutdown(ByRef custom As Array) Implements IDTExtensibility2.OnBeginShutdown
End Sub
End Class