in

Platinum Bay

Peace, Love and Visual Studio Team System

.NETicated

September 2007 - Posts

  • Visual Studio Extensi-Possibly

    Recently, I have been on a fix with Visual Studio eXtensibility (VSX), and have been experimenting with Visual Studio automation. Extensibility is one of the pillars of Visual Studio, and there are so many things you can do. Once you get a handle on it, the possibilities are unlimited.

    Or are they? My last post mentioned a problem, two actually, that I encountered while trying to create a debugger visualizer for the 'System.__ComObject' type. Here is another Visual Studio add-in I attempted to build without success:

    Source Control Switcher

    To change the source control provider in Visual Studio, you have to navigate to the Tools menu and choose 'Options…'. Then select 'Source Control' from the TreeView and find the desired provider in the dropdown. What a pain. I have source control set up at home for my projects, a couple CodePlex projects, and a work source control environment to switch between. I thought it would be wonderful to have a dropdown in a toolbar to allow me to switch source control providers.

    Unfortunately, there are no hooks in the add-in model to allow for this. There is a DTE.SourceControl object, but it only allows for working within the currently selected source control provider. For those familiar with the add-in model, there is also an option to use EnvDTE.Properties("", ""), but it cannot be used to access the Source Control properties.

    I found some tools out there to do this – sorta. They all use the registry and require you to close and re-open Visual Studio. Not an ideal solution.

    I may have to move this project up a notch to tier 3 and see if this is possible with the Managed Package Framework/Visual Studio SDK. I found a IVsSccToolsOptions interface in the MPF, maybe that will work? We'll give it a go.

    Isn't pushing the envelope fun? Speaking of envelope, I may need some SOAP after all this getting down and dirty.

  • System.__ComObject Unvisualized

    In preparation for my upcoming talks at the CMAP Code Camp and Philly .NET User Group meetings, I have been experimenting with Visual Studio add-ins and debugger visualizers. I built a cool tool window add-in I call 'Command Monitor' that shows me commands and the associated key bindings whenever a command event is fired. But working with the EnvDTE model requires working with COM objects in the form of System.__ComObject types and they aren't so pretty. So, I thought, why not build a debugger visualizer to make System.__ComObject types easier to debug.

    The first step was to create a base debugger visualizer, as shown in the following code sample.

    Imports Microsoft.VisualStudio.DebuggerVisualizers

    <Assembly: DebuggerVisualizer(GetType(ComObjectVisualizer), Target:=GetType(System.__ComObject), Description:="View System.__ComObject contents.")>
    Public Class ComObjectVisualizer
        Inherits DialogDebuggerVisualizer

         Protected Overrides Sub Show(ByVal windowService As IDialogVisualizerService, ByVal objectProvider As IVisualizerObjectProvider)
             Dim typeName As String = Microsoft.VisualBasic.Information.TypeName(objectProvider.GetObject)
             Dim t As Type = Type.GetType(typeName, True, True)

             Using form As New ComObjectDisplayForm
                form.ComObject = t
                form.ShowDialog()
             End Using
         End Sub

         Public Shared Sub TestShowVisualizer(ByVal objectToVisualize As Object)
             Dim visualizerHost As New VisualizerDevelopmentHost(objectToVisualize, GetType(ComObjectVisualizer))
            visualizerHost.ShowVisualizer()
         End Sub
    End
    Class

    There is only one problem with the above code, albeit a very large problem (there are actually two main problems, correctly guess the other one and you could win a $25 gift certificate to ThinkGeek.com1 Contest Details Below ). The type 'System.__ComObject' is marked Friend in mscorlib, and that means the code won't compile – you can't reference a Friend type in another assembly. After digging around in Reflector and looking at base types (MarshalByRefObject) and inherited types (none), I finally settled on a more round-about approach. I realized that I might be able to use ILDASM to get the IL, change the type, and use ILASM to compile it back into a DLL. So I found another type in the System namespace that importantly also contains 11 characters, namely the 'ArgIterator', and added a post-build event to my project.

    Here's the abbreviated version:

    ildasm /OUT="ComObjectVisualizer.il" "ComObjectVisualizer.dll"
    cscript replace.vbs "ComObjectVisualizer.il" "61 72 67 65 74 5F 53 79 73 74 65 6D 2E 41 72 67 // arget_System.Arg" "61 72 67 65 74 5F 53 79 73 74 65 6D 2E 5F 5F 43 // arget_System.__C"
    cscript replace.vbs " ComObjectVisualizer.il" "49 74 65 72 61 74 6F 72 2C 20 6D 73 63 6F 72 6C // Iterator, mscorl" "6F 6D 4F 62 6A 65 63 74 2C 20 6D 73 63 6F 72 6C // omObject, mscorl"
    ilasm /DLL /DEBUG /OUTPUT=" ComObjectVisualizer2.dll" "ComObjectVisualizer.il"
    XCOPY " ComObjectVisualizer2.dll" "...My Documents\Visual Studio 2005\Visualizers\ComObjectVisualizer2.dll" /YS

    The post build event performs the following steps:

    1. Runs ILDASM on the assembly.
    2. Calls a vbs file to do a find and replace, changing 'ArgIterator' to '__ComObject'. This gets a little tricky because the IL uses a hex representation of the assembly attributes value.
    3. Run ILASM to compile a new DLL.
    4. XCOPY the new assembly to the 'My Documents\Visual Studio 2005\Visualizers' folder.

    When it compiled, I was totally stoked – I had solved it, this was awesome, what else could go wrong. Yeah, funny thing with making that assumption.

    I fire up Visual Studio with my add-in project, set a breakpoint, and start debugging. When the breakpoint hits, I attempt to visualize an object of type 'System.__ComObject', and I get the following exception:

    Aw crap. A quick check in Reflector confirms it – System.__ComObject has neither a default constructor nor a serializable attribute. But why would it need to be serializable? Using the debugger DataTips, I am able to drill down and discover that under the covers, the debugger visualizer sub-system is using .NET remoting which uses serialization.

    Unfortunately, it appears there is no way around this issue. I'll certainly keep my eyes open, but for now, this great tool will have to wait.

     

    1 $25 to ThinkGeek.com to the first person that finds the other main issue I am thinking of. Must be the other issue I am thinking of. Other issues are certainly welcome, but not valid to win. Prize awarded in the form of a gift certificate and is not redeemable for cash, lottery tickets, or NASA space flights. Prize will be awarded once I remember my password to ThinkGeek.com. Contest is open to living, breathing human beings and really smart chimpanzees only. No purchase necessary, though if you want to send me money, I don't mind. Void where prohibited by local, state, federal and federated space colony laws. Employees, partners and Java fanatics and their immediate family members are not eligible to win. Contest expires at midnight on October 18th, 2007 or at the first correct answer, whichever happens sooner.

  • Community Server Calendar

    Ok, one more post about Community Server. Well, not so much Community Server, but an add-in I built for it. As you can see up in the menu bar there is a new link for Events. This is my local and national event calendar. I'll try to stay on top of local events especially – user group meetings, Code Camps, Pub Nights, MSDN events, etc.

    The calendar is fully integrated into the data layer, business layer, admin and control panel sections, as well as the caching engine and chameleon. It was a fun experience, and believe it or not, building the calendar control itself was probably the easiest part.

    And yes, I know there are still some bugs. For some reason, events past the next month are not showing up (resolved 9/22/2007), and the sub-calendars are not being filtered (resolved 9/23/2007). Those will get resolved whenever I get a round tuit (see left). If you find other bugs, let me know.

  • I Broke the Code

    No, not THAT code. I have no idea where the lost treasure is. Andy posted Wednesday about a Red-Gate contest to Break The Code. I figured I'd give it a try and whadya know, I broke the code! It's pretty cool, I've wanted to get my hands on Ants Profiler for some time now. It's a great tool, and we should always be testing the heck out of our code as we write it, because remember:

    Errors found early are errors found cheap!

  • Philly .NET Code Camp 2007.2 Prologue

    Philly .NET Code Camp 2007.2 is now history. The presentations have been given, including mine, the swag raffled, the food and snacks eaten, and I'm sure many folks traveled home enriched and empowered. For those of you who were unable to attend, you missed a great time. Not to worry though, we will be having another Code Camp in January.

    I was fortunate enough to be a presenter yesterday – my topic was 'Intro the Visual Studio 2005 Team System'. I was warned that it may be a tough topic to do, but it was my hope to present the vital fundamentals in a clear and understandable format, and the feedback I received was very positive. It was also my first experience presenting to a group, and it was awesome! I was not nearly as nervous as I thought I would be, though I certainly learned a lot to improve for next time. I won't have to wait long either – I will be presenting at the next Philly .NET User Group meeting on October 17th.

    My favorite session yesterday, apart from my own experience, was by Miguel Castro (photo right) titled 'Recruiters: the Good, the Bad, and the Ugly.' It was a very conversational presentation that hit home for everyone in the room. Andy Schwam also did a cool job of explaining custom user and server controls in ASP.NET and gave his attendees something they could go home and play with immediately. Very cool!

    See you in October.

  • I’ve Been Tagged

    In May I was blog tagged by Andy Schwam. So here are five things you may not know about me:

    1. I am a .NET fanatic. Wait, you knew?
    1. I had my own roadside assistance business when I was a late teen. I was on 476 (Blue Route), 76 (Schuylkill Expressway) and 95 around Philly helping motorists with everything from dead batteries to flat tires, fuel, and accidents. I also was a mechanic for a time and drove a tow truck.
    2. I grew up in Wayne, PA, but have since lived in the Adirondack Mountains in upstate New York (an hour from a stoplight), the eastern shore of the Chesapeake Bay in Maryland, New Jersey and Indiana. Now I am back in suburban Philadelphia.
    3. When I was in high school I was big into bicycling. One summer I averaged 50 miles a day, every day. My dream at that point was to be a cyclist at the Sydney Olympics in 2000. I'd still like to visit Australia some day, and New Zealand while I'm there.
    4. I am a hydrophile, and a certified open water diver. I love water – swimming, diving, kayaking, sailing, and boating. I loved the Changing Earth stream table (erosion) exhibit at the Franklin Institute when I was a kid. I also like driving through puddles and the snow.
    5. I love music, most any music. I am also a songwriter; I play guitar, the keys, and sing (and pretty well I'm told, though smoking doesn't help). I currently use ITunes on an old IMac and a Korg Trion Pro-X Studio to record whatever comes to mind. I have a couple of complete songs, but so far nothing that's been published. Growing up, I was neighbors with Tommy Conwell for a couple years. I almost always have a tune in my head.

    BTW, I traced this tag backwards a little ways:

    It's starting to branch, and that's where I call it quits.

    Now I get to tag a few people, in no particular order: Rick Strahl, Todd Bleeker, Kevin Goff, and Scott Watermasysk.

  • Reset the Visual Studio Environment

    Every now and again, I will manage to completely completely hose my Visual Studio environment. It is usually because I am trying to do things way outside the box, but that's the fun part.

    The crappy part is trying to get it back to normal. And as always, you have a couple options:

    1. When I first install Visual Studio on a computer, I go through all the settings and windows and get everything 'just right.' Once you have Visual Studio set up to your liking, go to "Tools" > "Import and Export Settings…", and export your settings. If you hose it in the future, you can import those saved settings.
    2. Sometimes though, you can't even get to the Tools menu (yes, I've done it, but I don't remember how). There are a couple of command line options to reset the environment in these situations.

      Reset Settings

      The command "devenv /resetsettings" will restore Visual Studio back to its original factory state. If you have previously saved your settings from option 1 above, you can pass them as a parameter: "devenv /resetsettings <SettingsFile>".

    For more Devenv command line switches, check out the MSDN article.

  • Visual Studio: Immediate Window Debugging

    I love debugger visualizers. For the most part, they work great. But debugger visualizers aren't much help when trying to examine arrays of objects or non-generic collections. In the example below,

    In this particular instance, I wanted to see the names, types and values for each item in the command1.Parameters collection. Similarly, the Locals window didn't help either.

    Here is where the Immediate Window comes to the rescue. I can get the value I want my using the following syntax:

    ? command1.Parameters("@sqlPopulate").Value

    The question mark at the beginning tells the Immediate Window to output the results, as in the following example which will get the name and value of parameter 2:

    ? command1.Parameters(2).Value
    5 {Integer}
        Integer: 5 {Integer}
    ? command1.Parameters(2).ParameterName
    "@PageSize"

    The beauty, as you can see, is that I can use full .NET syntax to work with the objects in scope at the current point of execution, and you get IntelliSense to boot.

    Have fun!

     

Powered by Community Server (Commercial Edition), by Telligent Systems
© Platinum Bay | Some Rights Reserved Creative Commons License

Disclaimer: The information in this weblog is provided "AS IS" with no warranties, and confers no rights. This weblog does not represent the thoughts, intentions, plans or strategies of my employer. It is solely my opinion. Feel free to challenge me, disagree with me, or tell me I'm completely nuts in the comments section of each blog entry, but I reserve the right to delete any comment for any reason whatsoever (abusive, profane, rude, or annonymous comments) - so keep it polite, please.