Tuesday, July 31, 2012

Running Visual Studio (or Any Program) As An Administrator Without Prompting for Elevation

Update: this fix hasn’t been as comprehensively effective as I hoped. Some things work well, but I’m still running into escalation issues. Sigh…

As a developer, I often find myself doing things that only administrators can do. This is especially true since I work primarily with web applications within IIS, since related activities require elevation.

For years, I have simply launched my Visual Studio instances from a “Run as Administrator”-decorated short cut on my task bar like this:

SNAG-0051

Keep reading—there’s a better way than this for frequently used programs!

BUT—that eventually drove me crazy enough to try something better because:

  • I constantly see the UAC elevation dialog
  • Because the app is running elevated, files that would normally open in it won’t open when double-clicked (solution/sln files, particularly)

Today I finally got tired of it and spent eight minutes figuring out how to do this better. I followed these instructions to add a compatibility fix to the app so that it always runs as the user invoking it, which is me, and I’m an admin. Here’s the gist (slight additions to the referenced instructions):

  1. Download this thing: Microsoft Application Compatibility Toolkit
  2. Run the 32-bit version of it (not 64-bit version—both are installed if you have a 64-bit machine)
  3. Add the new "application fix” to the custom database. Choose your app (devenv.exe for me) and give it the “run as invoker” fix
  4. Instead of opening a command prompt and installing it, just go to File > Install

Then I removed the “Run as Administrator” changes I made years back and things work great; my complaints above are fixed.

Careful users will note that this fix will probably break if the program is changed since many of the executable’s attributes are used to identify the program for fixing:

SNAG-0052

You can customize those when you create the fix, but I’m sticking with the defaults, which seem very narrow. I prefer to update the rule if the executable changes than have a new executable automatically receive the special treatment available through the compatibility fix.

Wednesday, July 25, 2012

Patching jQuery Validation for the iOS Date Picker

If you’re trying to use native datepickers with <input type="date"/> in your app and the jQuery Validate plugin for validation, here's something you probably need to know.

I discovered, when testing my app on an iPhone, that the jQuery Validate plugin wasn’t working on my date inputs. It would always mark them invalid. Huh.

I dug into it and found that this is how it determines if a date is valid:

// http://docs.jquery.com/Plugins/Validation/Methods/date
date: function(value, element) {
    return this.optional(element) || !/Invalid|NaN/.test(new Date(value));
}

That is, it just passes the string to be tested to the Javascript “Date()” constructor and checks to see if something back comes back.

OK…what’s going on then? I logged the value of the input and confirmed that it’s in the sensible ISO format I thought it’d be in:

2012-07-17 

After an embarassingly large amount of hunting in the wrong places, I eventually uncovered that validation code above and simple ran it:

2012-07-18 fiddle.jshell.net:23
Tue Jul 17 2012 20:00:00 GMT-0400 (Eastern Daylight Time) 

OK, so that makes sense in Chrome—the validation works in Chrome. So I ran that in iOS and…it failed! Here’s my commit message after I figured this out:

// patch the validate "date" method to accomodate iOS-style ISO dates
// because some browsers (including Chrome 19+ and iOS) support HTML5 date
// inputs, but some of those same browsers' Date() implementation
// doesn't parse them... WUT?! I'm looking at you iOS

This is madness. iOS 5’s Date() can’t parse what has got to be the easiest to parse date string ever.

Enough grumbling…what do we do? My first solution involved using the other date parse rule in the Validate plugin:

// http://docs.jquery.com/Plugins/Validation/Methods/dateISO
dateISO: function(value, element) {
    return this.optional(element) || /^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}$/.test(value);
},

That worked, since it just matches a simple yyyy-MM-dd pattern. I (of course) do server side validation, too, so I’m not worried about a user entering a syntactically correct, but practically incorrect date like 2012-02-30.

Rather than change all my inputs to use this alternative rule, or mess with my validation routine (I’m using the unobtrusive flavor)—I’d really like to just leave all that be, I decided to patch the first validator like so:

if ($.validator) {
    var originalDateValidator1 = $.validator.methods.date;
    var originalDateValidator2 = $.validator.methods.dateISO;

    $.validator.methods.date = function (value, element) {
        var isValidDate =
            originalDateValidator1.apply(this, arguments) ||
            originalDateValidator2.apply(this, arguments);

        return isValidDate;
    };
}

Quite simply, this just runs both of the date checkers and returns true if either of them pass.

In addition to not having to actually change any of my HTML, this code sits outside the library itself (it’s in my global.js file) so I can still update my plugins or load them from CDNs without fear. Oh, and if a user enters a date in the usual MM/dd/yyyy format in a browser that doesn’t support the native datepicker, the validation will still pass.

Hopefully Apple fixes this issue…

Let the Browser Handle the Datepicker (if it can)

I built a simple data entry app a while back and took the opportunity to try out a lot of neat new things in the web world. This included using Modernizr to detect native date picker support shipping in some browsers.

Traditionally, I’d just toss a Javascript date picker like the one from the excellent jQuery UI library when needed but now that browsers are starting to support other input types, e.g. <input type="date"/>, it’s possible to use the JS pickers as a fallback.

This idea isn’t novel with me, of course. I first saw it in one of Scott Hanselman’s talks (I can’t find a link at the moment, but I did find another MS blogger that does pretty much the same thing in great detail). If what I present below is too light on detail, go read his post.

Here’s how I did it in my ASP.NET MVC project:

First, create an editor template to render DateTime properties:

// in Views/Shared/EditorTemplates/DateTime.cshtml
@model DateTime?
@{ 
     var value = (Model != null && Model != DateTime.MinValue)
        ? Model.Value.ToString("yyyy-MM-dd") 
        : ""; 
}
@Html.TextBox("", value, new { type = "date" })

Now whenever you call “EditorFor” with a DateTime in a view, it will use that EditorTemplate to render it. If you’ve been using “EditorFor” all along, you’re in good shape.

Then the only other thing you need is to attach a datepicker if the browser needs it. I dropped this into my global scripts file, which runs on every single page:

// attach the jquery datepicker unless the current browser has one
if (!Modernizr.inputtypes.date) {
    $("input[type=date]").datepicker();
}

The theory here is that now when a browser adds support for native datepickers, the site will automatically stop adding the jQuery datepicker. Slick.

Here’s an example. If you try this in Chrome (added sometime on or before version 20…?), the second input should be a native datepicker (here’s a version with the jQuery datepicker, too):

<input />
<input type="date"/>

If those look the same in your browser, here’s what you’re missing:

SNAG-0045

Oh, and by the way, this is especially great for mobile devices—this is supported on iOS but not much else (yet).

Saturday, July 14, 2012

Building Cabers for your Summer Olympics

Let’s face it: you’re not an Olympian. Great, I’m relieved to get that out of the way.

Starting with the Summer games in 2008, my company has held its own version of the Olympics. We had a fantastically memorable time in 2008, and again in 2010 (Winter), and are ramping up again for the 2012 games on Friday.

My contribution to the organization of the event this year is the caber toss. Or really just the cabers themselves. Apparently a caber toss is a Scottish thing where you launch 175 lb., 19’ birch trees (the cabers) for distance and accuracy. Obviously we’re not going to do exactly that (we’re a bunch of wee engineers) so our approximation will be constructed from pool noodles. Approximate equipment for an approximate event (this isn’t actually an Olympic event), I guess.

Here’s how I made ours.

Bill of materials:

  • 42 pool noodles (I bought a mostly whole box from my local dollar store for …$42)
  • Lots of duct tape (I used 2-20yd rolls from Target for $7)
  • Uh… that’s all

The above materials yield 2-12’ cabers. Your mileage may vary as I’ve learned that the length of a pool noodle is not consistent from place to place or box to box.

So go get those noodles:

11-IMG_3165

I built mine in bundles of seven (one in the middle, and six surrounding it all hexagon like):

04-IMG_3172

Here’s one thing that I hope will help a lot during the games: I offset three across the middle by 50%. So four back, three forward (imagine pulling the two yellow and one blue noodles above half-way out of that bundle as a starting point). This overlap will hopefully help things stay together. This means that I have a joint about every 2’ or so where 3-4 new noodles are added.

I found a single rubber band to be very helpful while taping each joint:

10-IMG_3166 09-IMG_316708-IMG_3168 07-IMG_3169

06-IMG_3170

OK, I’m probably over explaining this…it’s really pretty obvious when you do it.

I found that the tape didn’t stick all that well to the foam. This is nice if you want to undo some taping, but not so super for strength. I think doing three rings at each joint, though, should hold up well. Just make sure you have plenty of overlap onto the tape itself so it doesn’t unravel.

When you run out of noodles, you’ll have three or four sticking out. Cut those off, and use the amputated noodles to fill in the opposite end. These things cut ridiculously easy with regular old scissors:

05-IMG_3171

At this point, I had a single 24’ long bundle of noodles. I cut it in half and capped all the ends with a very generous amount of tape to make two bundles:

03-IMG_31732012-07-14 14.27.17

As any god engineer would, I carefully estimated my materials before heading to the store and ended up with the following waste:

01-IMG_3175

And they’re ready:

02-IMG_3174

We had originally considered putting a wood dowel down the middle for rigidity. Ultimately I decided to forgo any additional structure. These are stiff enough to toss, but bendy enough to make it interesting or funny to watch people try. Plus they are light and safer this way.

Now I just need to figure out how to actually get them to the office…

If you’re overwhelmed with curiosity about what an office Olympics might be like, check out photos from previous years (2008, 2010). Pictures from this year’s games will be up a few weeks after the event.