Thursday 2 September 2010

Forcing a build on when Visual Studios' Debugger starts

It been a while but boy have i been busy :/

Having read http://webproject.scottgu.com/CSharp/UserControls/UserControls.aspx and http://weblogs.asp.net/scottgu/archive/2005/08/28/423888.aspx and trying to implement it i found myself in a nasty situation concerning 2 problems. First of all when an error occurs on the markup side of a UserControl/Page/etc the debugger with show the error not on the file that exists on the external library but on the file that we copied in our Web Application/Site. Its quite easy when making very small changes to get confused and make the changes on the stale file. I haven't found a neat solution on this and unfortunately the solution with the embedded usercontrols didn't work for me. Maybe it has something to do with Visual Studio 2008


Secondly, and quite importantly, hitting F5 to fire up the debugger will not guarantee a build! The reason, at least with Web Applications, is that changes on markup files will do not mark the library as dirty. In fact, any "Content" file has the same effect. So changing some important bit that does not change any code file and then starting the debugger will not trigger a build and so, since we are using copy/paste deployment and this depends on the pre-build event, the actual file that the application will use is stale. I find it very funny that msdn's MVP's actually advise to do a manual build. Surely there must be a better way!


After some digging around i found that the user can tamper with Visual Studio's event via the Macro Designer.
The initial implementation used this code part http://www.mztools.com/articles/2007/mz2007020.aspx
but i soon found out that even when the debugger is running, when entering Content files the ide will change to designer mode. So after searching the various exposed events i made this little simple fragment

    Private _curDebugState As EnvDTE80.dbgProcessState

    Public Sub debuggerStateChangedHandler( _
        ByVal NewProcess As EnvDTE.Process, _
        ByVal processState As EnvDTE80.dbgProcessState) _
        Handles DebuggerProcessEvents.OnProcessStateChanged
        If _curDebugState = dbgProcessState.dbgProcessStateStop And processState = dbgProcessState.dbgProcessStateRun Then
            DTE.ExecuteCommand("Build.BuildSolution")
        End If
        _curDebugState = processState
    End Sub

There are of course other commands like Build.BuildSelection, Build.RebuildSolution so choose your preference and you're set!