Quick Hit: Speeding up Visual Studio builds for Solutions with Managed and Unmanaged projects

Unload the native projects (right click native project in solution explorer –> unload).  Any subsequent builds will not build the native projects which usually take much longer to build.

Visual Studio’s memory of which projects are unloaded in a solution appears to be stored locally so it won’t be checked in when the solution is checked in (you’re not checking in .suo files are you?)

Of course this isn’t helpful if you’re working on the native projects but greatly speeds things up when you’re only working on managed code.

Which Control Properties can be automatically saved and loaded with ApplicationSettings?

ApplicationSettings automatically persist and bind property values for a component under the following circumstances:

  1. The component implements IBindableComponent.
  2. The component has either:
    1. A PropertyChanged event for the specific property (e.g., TextChanged, ValueChanged, etc…)
    2. or the component implements INotifyPropertyChanged.

Since all controls inherit from System.Windows.Forms.Control and Control implements IBindableComponent for controls you really only need to worry about the 2nd requirement.  If the control has a property changed event for the specific property then it will probably be automatically persisted when connected to an ApplicationSetting property.

Application Resiliency for Standard Users

Windows Installer has a feature called “Application Resiliency” which, in a nutshell, attempts to make sure that an application’s components are in order before executing the application.

Application Resiliency checks are invoked on a few occasions:

  1. When the user clicks an installer shortcut (which is different from a regular shortcut though the difference isn’t entirely germane to this post).
  2. When the user starts the application via file association (e.g., double clicks on a file extension that’s handled by the app).

These features are configured by registry entries.  The presence of a special key, called a Darwin Description (and described here), causes Windows Installer to do the extra Application Resiliency checks possibly resulting in an automatic repair.

So far so good.  I’m happy to have extra help keeping an application’s components intact.

What happens if the application was installed by an Administrator but the first resiliency check occurs in the context of a user without admin privs?  For example, the administrator installs it then leaves.  The first user to use the application is a user without admin privs.

Some of the resiliency checks require accessing the msi installer package.  This package, at least for one particular installer creating program, is by default left in a location specific to the user that performed the install.

Since non-admin users can’t read this default location, they should fail the resiliency check.

The twist in this particular case is that the user only fails the resiliency check when it is invoked by file extension (e.g., they double click on a file extension that is handled by the app).

A few solutions come to mind.

  1. Use Windows Installer in the “no registry” mode.  This will fix the problem but you give up a lot of functionality provided by Windows Installer.
  2. Manually disable Application Resiliency by deleting the “Darwin Descriptor” registry value after install.  This is bad for several reasons not the least of which is that it relies on an implementation detail that might change.  It’s also hard to do because the registry value appears to be read-only.
  3. Make sure that msi installer package gets installed into a directory that any user can read (e.g., CommonAppData).

1 and 2 are tempting but IMHO these are hackish approaches with too many drawbacks to justify their use.  3 seems to be the way to go but is not entirely without drawbacks: some systems may be so tightly configured that there are effectively no directories that can be read by any user.

The (software) Rockstar’s Muse

Had to share some great linkage about the “Rockstar’s Rockstar” type of developer.

I don’t think having one or more of these types around can magically turn an awful business plan into the next iPhone (or whatever business plan included the iPhone). 

Amazon, as discussed in “Done, and Gets Things Smart”, is a case in point though I’d be surprised if there weren’t a few poking around in the beginning - if only to get the seemingly embryonic technology of the time working well enough to make a business.

However, they might just buy you enough time to make a mediocre business plan into a stellar one.  They do this mainly in 2 ways:

  1. The software they produce and/or architectures they put into place result in far fewer fires to put out.
  2. The software they produce and/or architectures they put into place tend to interface with other software/architectures well.

How do these 2 points conspire to make Rockstar’s Rockstar developers make-or-break components of a software team?  I’ll expand on these in a later post.

Why are unused properties accidents waiting to happen?

When it comes to class design I’ve tended to shy away from using what database types would call “de-normalized” objects.

In the world of Object Oriented Design the analogue of de-normalized tables are objects that have lots of fields most of which are null or unset.

These kinds of objects should be avoided because they depend on hidden knowledge.  They increase the amount of hidden knowledge necessary to work with a given system.

In a perfect world the purpose of an object would be obvious based on its name.  The same goes for its properties.  But when most of an objects properties are not used at any given moment you usually have an object that can take on radically different roles based on which set of its properties are set (or not null).

How is someone new to the code going to know which role the object is in at the time they’re looking at it?  <== There’s that hidden knowledge!

Although it’s tempting in a pinch to pile on the properties/fields of an object, especially when it’s sitting right there and you really need a piece of data, I urge you to resist the temptation.  The befuddlement you’re hoisting into the future my just land in the lap of your future self.

As always this rule of thumb should be taken with a healthy dose of skepticism.  Sometimes it’s necessary to de-normalize; either for performance reasons or because the design genuinely calls for it.