What the #&$^# is Windows doing this time? (and other Microsoft gripes)

Yesterday, while starting up my PC out of hibernate mode (an activity done about 250 times before), after entering my username and password, Windows stared at me with a blank blue screen and a task bar (i.e. the desktop color and nothing else). Windows was certainly doing something, because the disk was thrashing. This went on for about five minutes. No activity on my part (CTL-ALT-DEL, CTL-SHIFT-ESC for Task Manager, etc.) brought about a response during those five minutes. After banging my keyboard countless times (it’s amazing I don’t break more than one a year), Windows suddenly sprang into service as if nothing out of the ordinary happened.

Can someone please tell me what the #&^$&#^ Windows was doing during those five minutes, and if it was such a mission-critical operation that NO OTHER ACTIVITIES could be taken while they ran, why there is no notice in the event log? Heck, a progress bar or meaningless popup message would have been nice.

Today, I attempt to hit the F1 key to get “help” in Visual Studio 2003 (yes, we all need help sometimes). VS2k3 has been run many times in the past, and I keep it up-to-date with the latest MSDN updates (i.e. the occasional help file updates). After pressing F1, Windows Installer pops up. Deciding to give up all hope on getting the help I need (and understanding that a random Internet search is faster than Windows Installer), I click Cancel. After about four minutes, the “Canceling…” message disappears, replaced by a new “Please wait while Windows installs…” message. I click cancel again. I shut down Visual Studio. The Windows Installer finally ended it “canceling” process after ten minutes, and I have a new message on my screen: “Microsoft Development Environment has encountered a problem and needs to close…” Yeah, yeah. Thanks for nothing.

It’s amazing how Microsoft can do so many things well, yet can’t do some of the most important things right — like make a responsive operating system. Then again, I shouldn’t expect much more. After all, this is a company that delivered an excellent development framework (.Net) yet decided that the framework includes platform-specific implementations (now that WinFX stuff is a “core” part of .Net). It’s funny how I spend a good part of my development time customizing built-in ASP.Net controls to do what I want them to do and not do what they were designed to do.

My three biggest complaints with ASP.Net, in no particular order…

  1. Naming containers. I understand why, but they make it almost impossible to write client-side JavaScript code. Microsoft’s answer to that is to register your scripts in codebehind and reference “ClientID” properties, but that is hardly a programming solution.
  2. The insistence on formatting with TABLEs (which is finally being addressed with the CSS adapters).
  3. The single-form limtation of ASP.Net, the dependency on ViewState, and the whole rely-on-postback model (which translates fine to some applications but terribly to others).
  4. The general goal of not expecting developers to write code. I want to write code — I want to control my application. Enhanced ASP.Net controls (things like GridViews) should be add-ons, much like you buy a component library from a company like ComponentArt (whose WebUI suite I use often). Microsoft can make them if it wants to, but don’t force-feed it on everyone.

Yeah I know that was four, but I’m a bit peeved by Microsoft today. 🙂

Changing the autogenerated password format in the SqlMembershipProvider

Since working with ASP.Net 2.0, I’ve been using the included Membership API almost exclusively. There was one piece of it I was never crazy about: the autogenerated passwords created by the SqlMembershipProvider (and, presumably, other providers).

Let me rephrase that. I didn’t have a problem with the auto-generated passwords, which included many symbol characters. For me, it was simple enough to copy/paste the autogenerated password (which would look something like this: @&#eyue@^%#), log in, then change the password to something more memorable.

Unfortunately, I am not a good representative sample of the typical web user, and eventually I heard my clients complain about the “overly complex” autogenerated passwords. Despite the explanations of an easy workaround (copy and paste) and the added benefit of the complex passwords (more security), clients still complain.

I came up with a quick way to hack the SqlMembershipProvider to generate less complex passwords, and it was as simple as creating a new provider class that inherits from SqlMembershipProvider, then overriding the GeneratePassword method.

In the code sample below, the autogenerated password will create a fixed number of randomly generated symbols (based on the MinRequiredNonAlphanumericCharacters property), then add a series of randomly generated upper case letters to ensure a password of at least MinRequiredPasswordLength characters long (with a forced minimum of eight characters).

Using only upper case letters is just one example. You could just as easily use random digits (zero through 9), or random lower case letters. There is an argument for using random lower case letters instead of upper case letters, as people are apt to interpret an upper case “O” as a zero “0”, a problem that generally doesn’t exist with lower case letters.

Some day I may hash this out to be a more robust provider with more options on choosing the password formats, but for the immediate problem, it’s more than adequate.

namespace CustomProviders
{
public class ExtendedSqlMembershipProvider : System.Web.Security.SqlMembershipProvider
{
public ExtendedSqlMembershipProvider() : base()
{
}
public override string GeneratePassword()
{
Random rand = new Random();
StringBuilder newpassword = new StringBuilder();
int length = (this.MinRequiredPasswordLength < 8 ? 8 : this.MinRequiredPasswordLength); int symbollength = this.MinRequiredNonAlphanumericCharacters; int charlength = length - symbollength; for (int index = 1; index <= symbollength; index++) { newpassword.Append((char)rand.Next(33, 47)); } for (int index = 1; index <= charlength; index++) { newpassword.Append((char)rand.Next(65, 90)); } return newpassword.ToString(); } } } [/source] Apparently, this doesn't work in all situations. According to Lutz Roeder's Reflector, the CreateUserWizard control calls this: [source='c-sharp'] if (this.AutoGeneratePassword) { int num1 = Math.Max(10, Membership.MinRequiredPasswordLength); this._password = Membership.GeneratePassword(num1, Membership.MinRequiredNonAlphanumericCharacters); } [/source] The Membership class (a static class) has its own password hashing algorithm that ignores the hashing of the provider. Of course, for consistency, the PasswordRecovery control calls the provider's ResetPassword() method, which in turn calls the provider's GeneratePassword() method. This matches my testing where the custom provider outlined above will generate passwords in the alternate format when being reset (using the PasswordRecovery control), but initial passwords are in the original format (thanks to the CreateUserWizard control). In my opinion, this is a faulty implementation -- a provider system which is ignored in one respect and recognized in another. It should not be this way.

Simple rounded corners

A friend of mine was trying to get a rounded corner bar at the top of some web content. He already had the rounded corner images but didn’t know the HTML and CSS markup. I sent him over the following snippet of code as an example:

    <div style="width:100%;background-color:blue;height:14px;margin:0px;padding:0px;font-size:5%;">
        <div style="float:left;background-image:url('left.gif');width:14px;height:14px;">
        </div>
        <div style="float:right;background-image:url('right.gif');width:14px;height:14px;">
        </div>
    </div>

To understand, note the following:

  • The width:100% should be set the width appropriate to your content.
  • The width and height (14px in the example above) should be replaced by the actual width and height of your rounded corner images.
  • What’s with the font-size:5%? Making the font size very small will ensure that any white space will not create a block larger than the desired height (in our case, 14px).

The following bar was made using the above content, using images from this web site.

Viewing only important emails with GMail

About a year ago, I started transitioning all my mail to Google GMail, an excellent email solution (and certainly better than Outlook). When using GMail, I like to filter the inbox so I only see my most important emails — that is, those emails which are unread or starred. The simple way to do this is to enter the following as search terms:

is:starred || is:unread

The search results will show all messages which are starred OR unread. Perfect for looking at only those items in your inbox which need your attention.

Baseball players are gamers, too

To those folks that follow professional baseball and multiplayer online games, it should not be a surprise that Boston pitcher Curt Schilling is an avid gamer. Sony even organized an event with him in their EverQuest II game (a game that Mr. Schilling is an avid player of).

In early September, Schilling and others formed Green Monster Games to create “industry changing games”. Good for him — it’s good to see online gaming and wargaming fans are not just avid sci-fi readers and nerdy IT types.

Schilling hasn’t sat back idly, either — he’s even reached out to the MMOG community, and I found that he has posted quite frequently on the web site of the Fires of Heaven guild (a World of Warcraft guild).

Side thought: Those Fires of Heaven guys are hard-core — they raid seven days a week, 6+ hours a day, and expect members to participate in 90% of the raids. I guess I won’t be sending in an application. 🙂

Perhaps Mr. Schilling would be interested in what I’ve done with my online baseball game, CSFBL? Sure, it’s not MMORPG in the MMORPG sense, but it’s got staying power, and has done quite well considering it was built with no budget in my spare time. Let’s not forget to mention the significant work currently underway in rewriting it (an effort that will launch as ComputerSims Baseball), or the vision to branch out into multiple sports using a core league-based sports engine that is already being developed…

What do you say, Curt? We share common interests — baseball, MMORPGs (I’m the guy who developed EQ2Craft, a hugely popular resource for crafters in EQ2) — and a common belief in the power of online games to mold commerce and the community… Of course, you’d have to forgive me in one respect: I’m a life-long Yankees fan. I did, however, root for Boston in the 1986 World Series…