dotnet, gists, sublime comments edit

Sublime Text 2 has a nice feature where you can hit “Ctrl+B” or select “Tools -> Build” from the menus and, based on the current file type, a build system will be automatically selected and executed against that file.

I recently released an update to my MSBuild package for Sublime Text 2 that includes some “build variants” for MSBuild that specifically set Debug or Release configuration during the build. Basically:

msbuild yourscript.proj /p:Configuration=Debug

or

msbuild yourscript.proj /p:Configuration=Release

I didn’t know this was possible until recently or I’d have put it in from the get-go. Note it assumes either that your project is a standard .csproj or .vbproj, or that you’re using the standard “Configuration” variable name to denote build configuration. It also doesn’t do anything with platform, so whatever your project defaults to, that’s what it’ll build.

As it turns out, it’s not clear how you access build variants from inside Sublime Text and it’s not obvious - it doesn’t show up on the menu.

To access Sublime Text 2 build variants:

  • Open the Command Palette (either “Ctrl+Shift+P” or “Tools -> Command Palette…”).
  • In the window, type “Build:” to filter the list of commands. Note the colon “:” on the end there - it filters the list down to just the build commands.
  • Select the build type you’d like. For my MSBuild package, you’ll see:
    • “Build: Build” - default, no configuration specified
    • “Build: Debug Configuration” - specifies “Configuration=Debug”
    • “Build: Release Configuration” - specifies “Configuration=Release”

Build variants are not specific to my package - other packages may also provide build variants with other names.

Related to this,some folks have asked why I haven’t supplied a “build and run” option the way some other packages have. The short answer is: I can’t. Here’s why:

MSBuild is sort of a scripting language. You can write an MSBuild script that just copies a bunch of files around or zips some things up. You can have an MSBuild script that just generates some reports. Or maybe your MSBuild script kicks off several other MSBuild scripts, each of which build something.

Even if you narrow the scope to .csproj or .vbproj files (which, yes, are in MSBuild format), you can build a lot of different things - an .exe, sure, but what if it’s a web site project? Or a WCF service? Or an Azure project? What does “build and run” do then?

The reason Visual Studio is able to handle this is that it narrows the scope of its handling (only actual project files can have “startup actions” - you can’t have that for a .proj or .targets file); and it “knows” about different project types and how to start them up.

When you have a web site project, it “knows” that in your project properties you should be able to specify which URL you want to view when it starts up the browser… and it knows to start up IIS Express (or the VS dev server) to host the site. Further, when you have a solution (multiple projects that all build together - like an MSBuild script that triggers several other MSBuild scripts) you can specify which project(s) should be started up and which actions should be taken at that time. That’s why you see all those .suo and .user files out there alongside your solutions/projects. It’s a system external to the build system that maintains all that information.

You can “make Visual Studio ‘know’ about new project types” by installing VS add-ins and components. For example, when you install the Azure SDK, it tells Visual Studio about Azure project types and how to handle the startup action.

Unfortunately, all of that’s a bit beyond the scope of what I can provide in Sublime Text.

If you would like a “build and run” experience, I would recommend writing a small “wrapper script” that triggers your real script and build that instead.

For example, say you have a project “MyProject.csproj” that builds “MyProject.exe.” A wrapper might look like this:

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="BuildAndRun" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
  <PropertyGroup>
    <Configuration Condition="'$(Configuration)'==''">Debug</Configuration>
  </PropertyGroup>
  <Target Name="BuildAndRun">
    <MSBuild Projects="MyProject.csproj" Properties="Configuration=$(Configuration)" />
    <Exec Command="MyProject.exe" WorkingDirectory="$(MSBuildProjectDirectory)/bin/$(Configuration)" />
  </Target>
</Project>

In this way, the wrapper script knows what the “run” action is and you can still use the Debug/Release configuration build variants. Obviously if you have a web site or something other than a simple .exe, your “run”action is going to be more involved. I’ll leave that as an exercise for the reader.

General Ramblings comments edit

Almost a month ago now (wow!) Jenn, Phoenix and I went to Disneyland with my parents for a three-day park-hopping adventure.

It’d been four years since Jenn and I had been, and far longer than that for my parents, so we were excited to go. With Phoenix not quite being two, we figure she probably won’t remember much of the trip when she’s older, but she’s super into Mickey Mouse Clubhouse right now, so she’d at least have fun.

The first ride Phoenix went on was the Mad Tea Party tea cups. She loved it.

Phoenix riding the tea
cups.

I’m glad she did for a couple of reasons. First, she likes carousels but she hasn’t really been on much besides that. I was afraid the tea cups might be too much, but she wanted more and smiled and giggled the whole time, so that was a relief. Second, both Phoenix and I are big Alice in Wonderland fans, so I’m glad she had a good first ride on an Alice-themed attraction.

She was excited to see Mickey… but only from a distance. We tried getting her to give Mickey a hug but we quickly discovered she’s not into the costumed characters. “NO MOUSE! NO HUG! NO TOUCH!”

No mouse! No
hug!

She didn’t seem to have a problem with the human characters (princesses, pixies, pirates) but the costumed characters that weren’t human were only allowed within about 10 feet before the alarms went off. We even tried one of the “character breakfasts” where you eat and the characters walk around from table to table. That didn’t go over well. Chip showed up and tried to say hello and Phoe went all DEFCON ONE ALERT ALERT ALERT so Chip backed off and that was pretty much the end of that.

We had actually scheduled the character breakfast at “Goofy’s Kitchen” because last time we were there the characters got all the kids to come out and bang pots and pans and dance. Phoenix is all about that sort of thing and we thought it’d get her to relax around the characters. Apparently they stopped doing that because parents complained that as the kids were coming back from the dancing, the characters continued to walk around and mingle and the unseated kids would miss characters coming past their table. I dunno. I think I’d rather have the dancing.

Of course we all got hats…

Travis, Grandma, and Phoenix with mouse
ears.

…and Phoenix wore hers everywhere. Even now, a month later, she still loves that hat.

Phoenix and Jenn with mouse
ears.

She also ended up getting a Minnie Mouse dress, which she also wore all over (and still does).

Phoenix in her Minnie Mouse
dress.

The big new attraction was Cars Land in the California Adventure portion of the park. We saw most of it, but it was pretty packed - even in the middle of October - so we didn’t get to see the whole thing. We also sort of left that for the last day and ran out of time.

We did get to ride all the other rides - from Splash Mountain to Star Tours, the Grizzly River Run to Soarin’ Over California. We missed quite a few last time we were here so it was good to catch them this time. We’ll try for the Cars Land rides next time.

Jenn lost her sunglasses on the Indiana Jones ride last time we were here, so I had to match her and lost my sunglasses in “Captain EO.” You’re probably wondering how I lost my sunglasses in a movie… I was, too. They must have just fallen out of my pocket. I realized as soon as we got out the exit, but when I turned around to go back the doors had already shut so I ran around to the ride attendant and explained the situation. Since the next show had already started I had to wait the 17 minutes for the movie to end, then I could go back in through the exit doors and search. That was honestly a pretty rough 17 minutes. I wouldn’t have been so worried if they were just $50 sunglasses or something, but they’re prescription - way, way more than $50.

Anyway, I went back in and searched for the two minutes they give you between when one crowd leaves and the next is seated. I didn’t find them, even with the attendant’s help. I called out to the audience members to see if anyone saw them but no one did. Jenn and I then got to sit through “Captain EO” again, you know, because they won’t let us do any real searching, and we searched again for the two minutes. I got some pretty harsh rug burns on my knees from that. Finally, after the second round of “Captain EO” (which I am now thoroughly sick of) one of the audience members announced he’d found my sunglasses and handed them to me. Thank goodness. It was an hour lost, but a couple hundred bucks saved. Big props to Jenn for standing by me on that one.

One of the cool things we did was see the “World of Color” show at the end of the last day. That show is over in the California Adventure park and they have a nice water display with lasers, lights, and video projection all set to music. From an engineering perspective, I really liked it - you can get these light-up ear hats that have some sort of receiver in them and the lights in the show will coordinate with how your hat lights up. Really cool stuff. Jenn and I had to get the hats and wear them. (When you’re not within range of the broadcast, the hats flash random colors and are still really cool.)

It was a fun, but long, vacation and at the end I think we were all ready to go home. Phoenix was a trooper, really being good most of the time despite the record heat (~95F each day) and not getting a nap. Toward the end we were all tired, she was starting to get naughty, and we’d all walked our feet off. I think that’s part of what makes it a good one, yeah?

The whole family riding the trolley in California
Adventure.

I posted a few more pictures for folks interested. Good times, and I look forward to the next vacation.

dotnet, autofac comments edit

For those of you who use Autofac, I thought I’d provide a bit of a project update to let you know what’s going on.

First, there’s been a little shake-up in the project ownership role. Nick Blumhardt, original creator, will still be working on the project as a committer but has stepped down as an owner. Alex Meyer-Gleaves will remain an owner, and I’ve now been made a co-owner with him. Nick has posted a formal announcement in the Autofac newsgroup. Huge props to Nick for making such an awesome product; I hope I can help carry that forward with as much success.

Next, we’re working hard on the upcoming release of Autofac, which we’ll be calling 3.0. The core Autofac assembly will be a Portable Class Library so we can support WinRT, Silverlight, and full .NET. That will potentially mean a few small breaking changes, but it shouldn’t be too bad to adjust to. We’ll be adding NuGet packages for all of the contributed projects (which are now the “Autofac Extras”). Dependencies have been updated so we’ll link to more current releases. We’re running down the issues list to see if we can get as many resolved as possible before the final release. And we’ve done a ton of updating to the build and static analysis process so it’s easier to work on, easier to extend, and adds a lot more confidence to the shipping builds. I really think you’ll like it.

I anticipate that should all be showing up Real Soon Now. You can follow the progress on the Autofac newsgroup.

media comments edit

As part of my media center solution, I have a fairly rigorous media and metadata management process that goes on any time I acquire new media. I figured I might give folks a glimpse behind the curtain so you know what goes on. Broken down by media type, here’s how it goes from acquisition to “in the system.”

  • Audio (Music, Audiobooks)
    • CD 1. Add to Music Collector. - Enter the CD info, generally by bar code. - Clean up artist or album name data if needed. - Synchronize collection with Music Collector Online. 2. Add to iTunes. - Rip CD as Apple Lossless. Files end up on Windows Home Server for later serving via Asset UPnP. - Clean up metadata as needed - artist, album, cover art, etc. 3. Synchronize iPod. 4. File the disc. - Pull the disc, front cover, and back cover out of the plastic box. - File the disc with the front cover in a DJ box. - File the back cover in an expanding folder. - Recycle the plastic box.
    • Digital (MP3, AAC) 1. Download from original source (usually Amazon MP3). 2. Add to iTunes. - Drag into iTunes. Files end up on Windows Home Server for later serving via Asset UPnP. - Clean up metadata as needed - artist (last, first), album, etc. 3. Synchronize iPod. 4. Add to Music Collector. - Add the digital files to Music Collector. - Clean up artist or album name data if needed. - Link to a Music Collector album profile. - Synchronize collection with Music Collector Online.
  • Video (Movies, TV Shows)
    • Blu-ray 1. Add to DVD Profiler. - Update the local profile database for my existing collection. - Enter the disc info, generally by bar code. - Synchronize collection with DVD Profiler Online. - Backup the local profile database. 2. File the disc. - Pull the disc cover, discs, and inserts out of the plastic box. - File the disc with covers and inserts in a DiscSox storage set. - Recycle the plastic box.
    • DVD 1. Add to DVD Profiler. - Update the local profile database for my existing collection. - Enter the disc info, generally by bar code. - Synchronize collection with DVD Profiler Online. - Backup the local profile database. 2. Rip the disc and add to media center. - Rip the disc with DVDFab HD Decrypter. - Update the folder name with the disc image so XBMC can scrape data. - IMDb format for movies. - TheTVDB format for TV shows. - Update the DVDID XML file if needed for Windows Media Center. - Copy the disc image onto my NAS (Synology DS1010+) for later serving. - Start XBMC on my master computer (read/write access to the database) and let XBMC scraping add the new item to the database. - Verify/correct any XBMC metadata issues. - Start Windows Media Center on my master computer and wait for it to add the cached metadata XML file to the system. - Correct the metadata using DVD Library Manager including better cover scans. 3. File the disc. - Pull the disc cover, discs, and inserts out of the plastic box. - File the disc in a binder. - File the cover in an expandable folder. - File the inserts in a small photo box. - Recycle the plastic box. 4. Optional: Convert for Mobile Use (via Handbrake). If I do this, I put it into iTunes and then sync iPod and iPad.
    • Digital 1. Redeem the “digital copy” code (in iTunes). 2. Update any metadata as needed. 3. Sync iPod and iPad.

You’ll notice that, at this time, I’m not ripping Blu-ray discs to any media server/digital format. I don’t have a ton of them and they just eat disc space, so I’m not there yet. I’ve also still not figured out a good compression format that retains the surround sound, which is why I rip full images from DVDs.

You’ll also note that I don’t really buy digital videos. The only ones I have are from those “digital copy” things you get with some disc purchases. There’s no DRM-free equivalent that they sell videos in right now, so these are “neat” but aren’t my system of record and probably won’t be if I have anything to say about it. (Which, someday, I may not

  • thanks Hollywood…) The only time I even use these is if I’ve got my iPad on a trip or something. I don’t/can’t use them through my media center.

For all the folks that think maintaining something like this is free… now you see it isn’t. Or maybe it is if you don’t care about the housekeeping part, but I can see that after you get to a sufficient size then having no organization (or not caring) may render the system unusable, which is what I’m trying to avoid.