Creating Custom States and Columns Provider Shell Extension for Virtual Drive
The IT Hit User File System Engine provides integrated support for states and custom columns that can be displayed in Windows Explorer. Below we will describe how to implement custom states and columns shell extension for your Virtual Drive that runs as a COM inside main app, which also hosts your Engine instance. .
The functionality described in this article is available in IT Hit User File System v5 Beta and later versions.
Note that unlike context menu on Windows 11, custom states and columns handler does not require application identity.
Follow the steps below to implement custom states and columns shell extension in Windows Explorer:
1. Register Custom States and Columns
When registering virtual drive you will define custom columns that will appear for every item:
StorageProviderSyncRootInfo storageInfo = new StorageProviderSyncRootInfo(); storageInfo.Path = await StorageFolder.GetFolderFromPathAsync(path); ... var proDefinitions = storageInfo.StorageProviderItemPropertyDefinitions; proDefinitions.Add(new StorageProviderItemPropertyDefinition { DisplayNameResource = "Lock Owner" , Id = 2 }); proDefinitions.Add(new StorageProviderItemPropertyDefinition { DisplayNameResource = "ETag" , Id = 6 }); StorageProviderSyncRootManager.Register(storageInfo);
2. Provide Data for Custom States and Columns
Implement the IFileSystemItem.GetPropertiesAsync() method and return your columns data:
public async Task<IEnumerable<FileSystemItemPropertyData>> GetPropertiesAsync( IOperationContext context) { IList<FileSystemItemPropertyData> props = new List<FileSystemItemPropertyData>(); // Read LockInfo. if (context.Properties.TryGetValue("LockInfo", out IDataItem propLockInfo)) { if (propLockInfo.TryGetValue<ServerLockInfo>(out ServerLockInfo lockInfo)) { // Return Lock Owner data to the platform. var propertyLockOwner = new FileSystemItemPropertyData() { Id = 2, Value = lockInfo.Owner, IconResource = Path.Combine(Engine.IconsFolderPath, "Locked.ico") }; props.Add(propertyLockOwner); } } ... return props; }
3. Create Custom States and Columns Handler Class
In this step you will create a custom states and columns handler as COM exe running inside your main app. Create your custom states and columns provider class by deriving it from the CustomStateHandlerIntegratedBase class, provided with the Engine, and pass your Engine instance directly to the base class constructor:
[ComVisible(true)] [ProgId("VirtualDrive.CustomStateProvider")] [Guid("754F334F-095C-46CD-B033-B2C0523D2829")] public class CustomStateProvider : CustomStateHandlerIntegratedBase { CustomStateProvider() : base(Program.Engine) { } }
The handler will call the Engine instance that you pass to the constructor and than call the IEngine.GetFileSystemItemAsync() and IFileSystemItem.GetPropertiesAsync() methods when data for custom properties are needed.
You do NOT need to implement any methods in your custom states and columns handler.
You must decorate the class with the ComVisible, ProgId and unique Guid attributes. You will use them when registering your COM custom states and columns handler shell extension.
Do NOT use the GUID from this sample. You must create your own unique GUID for your provider handler, which is different from any other GUIDs used in your application.
4. Register Custom States and Columns Handler
Add the desktop3:CustomStateHandler and the com:ExeServer code tags to your packaged app manifest or sparse package manifest:
<Package xmlns:desktop3="http://schemas.microsoft.com/appx/manifest/desktop/windows10/3" xmlns:com="http://schemas.microsoft.com/appx/manifest/com/windows10" ...> <Applications> <Application ...> <Extensions> <desktop3:Extension Category="windows.cloudFiles"> <desktop3:CloudFiles> <desktop3:CustomStateHandler Clsid="754F334F-095C-46CD-B033-B2C0523D2829"/> </desktop3:CloudFiles> </desktop3:Extension> <com:Extension Category="windows.comServer"> <com:ComServer> <com:ExeServer DisplayName="VirtualDrive.ShellExtension" Executable="dummy.exe"> <com:Class Id="754F334F-095C-46CD-B033-B2C0523D2829" /> </com:ExeServer> </com:ComServer> </com:Extension> </Extensions> </Application> </Applications> </Package>
Note the "dummy.exe" in the executable path in com:Extension tag. By specifying a non-existent path to your handler location, the platform will properly load your handler from your main application.
Note that in case of a packaged app or sparse package your COM will be automatically registered on app install and deleted on uninstall. You do NOT need to install/uninstall it manually using regsvr32.exe or Win 32 API.
5. Run COM exe Server
In this paragraph we describe how to allow platform to find your COM object inside your application.
When starting your application create a LocalServerIntegrarted class instance and dispose it when the application is closed. Register your COM class using the LocalServer.RegisterWinRTClass() method call when starting the application:
using (var server = new LocalServerIntegrarted()) { server.RegisterWinRTClass<IStorageProviderItemPropertySource, CustomStateProvider>(); ... using (VirtualEngine engine = new VirtualEngine(); { ... } }
Note that menu and thumbnails handlers are registered using RegisterClass() method, while custom states and columns handler is registered using RegisterWinRTClass() method.
Showing Custom Columns in Windows Explorer
While icons show automatically in Status column in Windows Explorer, custom columns are hidden by default. To show custom columns use the "More..." context menu on the columns header in Windows Explorer.