The application directory bundle shell hack

In the words of the great Raymond Chen: In Windows, the directory is the application bundle but that is a poor excuse for the lack of some kind of application bundle or fat binary support. I usually don’t care about eye candy but it would be nice (and a fun experiment) if we could get a application directory to look and act like a real application bundle.

Folder icon customization has been around for years but desktop.ini got a new feature in Win7; you can add custom verbs to the context menu. This will enable us to take over the default action and do whatever we want when the folder is double clicked!

We begin with a pretty standard looking desktop.ini:

[.ShellClassInfo]
ConfirmFileOp=0
DirectoryClass=WndSks.ExecAppFolder
IconIndex=0
IconFile=app\foobar2000.exe
InfoTip=foobar2000
ExecAppFolder:Cmd="%%\app\foobar2000.exe"

DirectoryClass is used to specify the ProgId with our special verb and ExecAppFolder:Cmd is a custom entry I made up and it contains the command we actually want to execute (%% will be replaced by the folder path)

Next up is the registry entry for our ProgId:

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\WndSks.ExecAppFolder]
"CanUseForDirectory"=hex:

[HKEY_CLASSES_ROOT\WndSks.ExecAppFolder\shell]
@="RunAppFolder"

[HKEY_CLASSES_ROOT\WndSks.ExecAppFolder\shell\RunAppFolder]
@="Run Application"

[HKEY_CLASSES_ROOT\WndSks.ExecAppFolder\shell\RunAppFolder\command]
@=hex(2):77,00,73,00,63,00,72,00,69,00,70,00,74,00,20,00,22,00,25,00,53,00,79,\
  00,73,00,74,00,65,00,6d,00,52,00,6f,00,6f,00,74,00,25,00,5c,00,52,00,65,00,\
  73,00,6f,00,75,00,72,00,63,00,65,00,73,00,5c,00,57,00,6e,00,64,00,53,00,6b,\
  00,73,00,2e,00,45,00,78,00,65,00,63,00,41,00,70,00,70,00,46,00,6f,00,6c,00,\
  64,00,65,00,72,00,2e,00,77,00,73,00,66,00,22,00,20,00,22,00,25,00,31,00,22,\
  00,00,00

The hex goo is just the string wscript "%SystemRoot%\Resources\WndSks.ExecAppFolder.wsf" "%1" and this little WSH script is the final piece of the puzzle:

<?xml version="1.0"?><package><job><script language="JScript"><![CDATA[
var WS=WScript,
WSh=WS.CreateObject("WScript.Shell"),
FSO=WS.CreateObject("Scripting.FileSystemObject"),
a=WS.Arguments;

function IniGetValFromLines(lines,sec,name)
{
	// WSH does not have INI support?
	// We don't need true INI handling so we just fake it
	beg=lines.indexOf(name+"=");
	if (-1!=beg) {
		beg+=name.length+1;
		return lines.substr(beg).split("\r",2)[0].split("\n",2)[0];	
	}
	return null;
}

if (1==a.Length) {
	appfldr=a(0);
	inilines=FSO.OpenTextFile(FSO.BuildPath(appfldr,"desktop.ini"),1,-2).ReadAll();
	cmd=IniGetValFromLines(inilines,".ShellClassInfo","ExecAppFolder:Cmd");
	if (cmd) {
		cmd=cmd.replace("%%",appfldr);
		WSh.Run(cmd,5);
	}
}
]]></script></job></package>

I used to store this kind of shell stuff in %WINDIR%\system32\ShellExt but I don’t think that folder is used much these days so I just stuck it in Resources to get it out of the system root.

For the icon handling to work you need to make the folder read only (or system) and +s+h on desktop.ini to make it superhidden.

To install this as a single user you should replace HKEY_CLASSES_ROOT with HKEY_CURRENT_USER\Software\Classes and store the .wsf somewhere in your profile.

It should be noted that D&D does not work. It might be possible to work around this by creating a DropHandler but then this would not be a “Notepad only” hack 😉

It might even be possible to implement the menu and double click handling on older windows versions by using the CLSID and/or UICLSID hooks and some horrible hacks in the COM namespace handling but for now this is Win7+ only…

Advertisements

Tags: , , ,

One Response to “The application directory bundle shell hack”

  1. Anonymous Says:

    Wow didn’t know about this desktop.ini custom verbs feature. Desktop.ini also lost the ability to customize the folder background in W7 because ListView is not the default control in Explorer (but can be made the default one using a reg hack).

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s