Files as Folders

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. These files and images are organized in a hierarchy. Rather than write an application to allow users to view the contents of such a file, you may instead write a Namespace Extension that understands the file's format and exposes its inner content as a Shell item hierarchy, just like any other hierarchy in the Shell.

Note that such a hierarchy generally is composed of fully virtual items, unless the extension writes the file's content to the filesystem in some way.

For such a folder, the native proxy DLL must be installed with the "Namespace Location" parameter set to "no location" (i.e., an empty string). 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 as follows:

  • There is not a single "root folder" because 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 CBFS Shell project can support many file extensions.

The following sample code implements the Shell folder server:

    public class SevenZipShellFolderServer : ShellFolderServer
    {
        // CBFS Shell 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 is a check to ensure that 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 a direct a part of CBFS Shell because it cannot be fully generic, as it ultimately depends on how file extensions are owned and managed by the .NET server that you develop and deploy.

The following sample.reg file outlines the minimum recommended keys and values necessary for the Shell to recognize the extension. The "7Z_auto_file" name, a progid, will 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 GUID is usually {11dbb47c-a525-400b-9e80-a54615a090c0}, which corresponds to CLSID_ExecuteFolder, a well-known system GUID.

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

The following screenshot shows 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:\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 Explorer handles .zip files out of the box:


Copyright (c) 2022 Callback Technologies, Inc. - All rights reserved.
CBFS Shell 2022 .NET Edition - Version 22.0 [Build 8367]