File as Folder support

A namespace extension can allow users to browse the contents of a file like a folder, rather than have it presented as an item. For instance, archive files contain multiple, compressed or not, files or images, organized in a hierarchy. Rather than write an application to allow the user to view the contents of such a file, you can instead write a namespace extension that understands the file’s format and exposes its inner content as a Shell hierarchy, just like any other hierarchy in the shell.

Note such a hierarchy is in general composed of fully virtual items, unless the extension writes the files content in some way.

For such a folder, the project characteristics must be changed and the “namespace location” parameter must be set to “no location” as shown here:

File as Folder
support - Picture 83

In fact, this is not mandatory, but it’s unusual for such an extension to support file types and at the same time be available as a folder under the Shell namespace.

The implementation is very similar to other extensions. The main differences are:

There’s not a single “root folder” since the extension can be started from any file corresponding to the file extension(s) it supports.

The extension must register itself as a folder for the file extension(s) it supports. One single ShellBoost project can support many file extensions. It must also use standard ShellBoost registration explained in the Deployment chapter.

Here is some sample code that implements the Shell folder server:

    public class SevenZipShellFolderServer : ShellFolderServer
    {
        // ShellBoost will call that method each time an archive file is open using the Shell
        protected override RootShellFolder GetRootFolder(ShellItemIdList idList)
        {
            if (idList == null)
                throw new ArgumentNullException(nameof(idList));
 
            // this check to ensure we're not being called for anything else than what we expect (like a folder, etc.)
            var path = idList.GetPath();
            if (!IOUtilities.FileExists(path))
                return null;
 
            return new ArchiveRootShellFolder(this, idList);
        }
    }

Registration code is not directly part of ShellBoost since it cannot be fully generic, as it ultimately depends how file extension are owned and managed by the .NET server you develop and deploy.

Here is a sample.reg file the outlines the minimum recommended keys and values necessary for the Shell to recognize the extension. The “7Z_auto_file” name, a progid, can vary depending on your configuration:

Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Classes\.7Z]
@="7Z_auto_file"
[HKEY_CURRENT_USER\Software\Classes\7Z_auto_file]
[HKEY_CURRENT_USER\Software\Classes\7Z_auto_file\CLSID]
@="{13d8f906-6a6c-3a2c-5898-1f1e7b333712}"
[HKEY_CURRENT_USER\Software\Classes\7Z_auto_file\shell]
[HKEY_CURRENT_USER\Software\Classes\7Z_auto_file\shell\open]
[HKEY_CURRENT_USER\Software\Classes\7Z_auto_file\shell\open\command]
@="%SystemRoot%\\explorer.exe /idlist,%I,%L"
"DelegateExecute"="{11dbb47c-a525-400b-9e80-a54615a090c0}"

The first guid (in the CLSID key) must match the namespace extension’s Shell Folder class id. The second one is generally always {11dbb47c-a525-400b-9e80-a54615a090c0} which corresponds to CLSID_ExecuteFolder, a well-known system guid.

This feature is demonstrated in the SevenZip Sample. The application comes with some sample registration code in Program.cs (RegisterAsVirtualFolder and UnregisterAsVirtualFolder).

Here is a screenshot of a .7z file named “7z1900-src.7z” (this is a .7z file that corresponds to 7-Zip source code, downloadable from 7-Zip web site) that is in a d:\Aelyo\Tests folder. This file is opened and browsed like it is a folder. All items are fully virtual. The behavior is very similar to how Windows Explorer handles .zip files out-of-the-box:

File as Folder
support - Picture 84