Thursday, October 21, 2004

Control Panel Items

Since I'm on a roll with configuring stuff, there is a nice article on MSDN about configuring Control Panel Items. If you are a setup developer, this link will take you to the section that you should read.

Some things to note:

  • "...the DLL file must have a .cpl file name extension" - These control panel items ARE DLL's.
  • on "Windows 2000 and later systems, new Control Panel items should be installed in the associated application's folder." - Yep, no installation to SYSTEM like the old days!
  • The placement of a registry key dictates what shows up in the Control Panel. Remember to respect per-user installations! (Yes! it is a bug, a security one, and a bad one)
  • If you must support the "old" pre-Windows 2000 method, only do so on the pre-2000 OS.
  • Yes. you can extend System Control Panel Items.
  • You can also specify a category for the item in Windows XP or better, for users using the default control panel view.
  • For MSI folks, there is nothing in any of the Standard Actions that will help you.

Larry talks HKCR

If you recall, I recently blogged about the fact that HKEY_CLASSES_ROOT key is not a real registry hive. Larry Osterman from Microsoft recently posted a "What is wrong with this code?" series and covers the HKCR issue extremely well in the answer section. If you develop services, this one is worth a read.

Raymond talks about registering shell extensions

As you can tell, I'm catching up on reading some of my favorite blogs... Raymond Chen from Microsoft wrote a really nice article about registering shell extensions. Setup developers should take note of how Windows deals with what you put in those keys.

What is a shell extension (also known as Verbs)? This is what Windows uses to determine what to do (or what right-click options to provide) when clicking on a file with a specific extension. Read this link to find our more. I'll wait...

In the setup world, I believe when you run a program from a setup most vendors use the ShellExecute() API. If this is the case, when you launch a readme at the end of an installation by simply specifying "readme.txt" the default "open" verb (on a fresh Windows installation for a text file this will be Notepad) will be run. If the method of running an application in your authoring tool uses CreateProcess() , it will likely result in an error if you simply give it "readme.txt". For MSI based installations, many people may use the tutorial method described in the Platform SDK. I leave it as an exercise to the reader to see what that one uses! Any guesses based on the specifications for the tutorial mentioned in this document?

If you read the MSDN documentation for these functions - which are linked to above - you will understand this quote from the article: "Consequently, the shell mistakenly believes that the program name is "C:\Program", which it cannot find." This can be a security issue if a malicious program installs itself as "C:\program.exe". Please make sure you are registering extensions correctly - even if the installation design document you are given dictates otherwise.

Saturday, October 16, 2004

Custom Action Tutorial coming soon to a blog near you...

Since I didn't get any responses for suggestions for a C++ custom action, I took a look at the newsgroups and found this post where the author wants to detect if an application is running and prompt the user, close the application, etc. Developing a custom action to handle this would be a good thing for the community, as it is a fairly common request.

This also meets the bill for covering almost every aspect of a robust custom action - user interaction, running in silent mode, custom table, validation, etc. The one thing it does not implicitly have is a rollback action. I will "fake" a rollback action for demonstration purposes.

I also decided on a multi-part series as the best format for this.

  • Part one - describe the specifications and set up the development environment.
  • Part two - create a "Hello MSI" custom action and insert it into a sample MSI.
  • Part three - debugging the "Hello MSI" custom action.
  • Part four - add tables and other required entries to the MSI.
  • Part five - add code to read the tables.
  • Part six - add code to close the application. I'll likely gloss over this pretty fast, as killing an application is not the true focus here.
  • Part seven - testing the custom action.
  • Part eight - creating documentation for other developers.
  • Part eight - Creating validations for the action and tables.
In the process of developing this, I will loosely cover internationalization concerns, Unicode support, MSI Custom Action fundamentals, and more. I will "try" to follow the format of MSDN documentation in the process.

My intention is to complete the series first and post one new part every couple of days to keep the writing style similar and assure completeness. With my current workload, I'd guess part one would be published in late October.

Does anyone have specific feature requests for this Custom Action? Topics not mentioned here that should be covered?

Monday, October 11, 2004

.NET Deployment

I came across this blog entry that talks about this blog entry. So this blog entry is talking about a blog entry that is talking about a blog entry - whew!

The crux of the story is how an application based on the .NET Framework should be deployed. The post goes into adding the MSM for the framework, etc. The killer quote from the first blog entry by Stéphane Rodriguez is "What should I, as a developer, think about a development framework which by design involves hacks only for my app to be deployed?"

Amen, sister!

I blogged previously about how difficult it is to determine the .NET Framework and again when Aaron Stebner produced some sample code to check this. Stéphane hit exactly on what was in the back of my mind: Why is this so hard?

In theory, the .NET runtimes are mostly backwards compatible. The version detection scheme is not future compatible - I have no idea how to detect the .NET 2.0 RTM runtime today as a setup developer. Even if I can detect this, there are no guarantees that "Compatibility and Breaking Changes" haven't affected me. At least if I could detect the version, I could intelligently deal with it. I may alert the user that the framework version installed has not been tested with my application and let the installation continue. Then again, I may choose to have the old framework downloaded and installed. Or really anything.

The problem that exists is (as a commenter to the quoted blog points out) very similar to Java's problems. Microsoft should have learned from this and done a better job. Looks like they haven't - and mostly from a documentation perspective from what I can tell.

Lastly, there is a lack of tools and guidance to setup developers and how they should handle deployment. In an MSI, why can't I simply tell the engine/tools that my application targets one or more versions, and let the engine handle the detection job along with a warning if installed framework version is greater than what is targeted?

Why must stuff that should be so easy be so difficult?