My app adds some custom metadata to files. I want to display it in Windows Explorer like this:
or this:
Is there a way to do this in .NET?
There are two approaches to building custom columns in Windows File Manager: using Windows Property System and Property Definitions for Cloud Storage Provider. You will typically use the first approach to create custom properties for file types that you own. You will use the second approach when displaying custom data from your document management system or any other storage.
You can create custom properties for specific file types in Windows Vista and later versions. These properties can be read-only or read-write. As well as they can be indexed by Window Search indexer and participate in the search. There are some limitations:
...property handlers cannot be implemented in managed code and should be implemented in C++.
In Windows 10 Creators Update and later you can add custom columns for file systems created using Cloud Sync Engine API (Storage Provider, Cloud Filter API). This API is used in such tools as OneDrive. You will need to register a Cloud Storage Provider sync root with custom properties definitions, provide data for your custom columns and finally implement a Cloud Storage provider using Cloud File/Cloud Filter API.
Property definitions are not tied to a file type and can be added for all files. Also, even though only some API is available in .NET you still can call Win32 functions and build a cloud provider using managed code only.
Registering the Cloud Storage provider. Here is an example of the Storage Provider registration with custom columns in C#:
StorageProviderSyncRootInfo storageInfo = new StorageProviderSyncRootInfo();
storageInfo.Path = await StorageFolder.GetFolderFromPathAsync("C:\\Users\\User1\\VFS\\");
...
// Adds columns to Windows File Manager.
// Show/hide columns in the "More..." context menu on the columns header.
var proDefinitions = storageInfo.StorageProviderItemPropertyDefinitions;
proDefinitions.Add(new StorageProviderItemPropertyDefinition { DisplayNameResource = "Lock Expires", Id = 2, });
proDefinitions.Add(new StorageProviderItemPropertyDefinition { DisplayNameResource = "Lock Scope", Id = 3, });
StorageProviderSyncRootManager.Register(storageInfo);
A complete registration example could be found here.
Providing data for property definitions. To provide the data for the columns you will use StorageProviderItemProperties.SetAsync() call:
IStorageItem storageItem = await Windows.Storage.StorageFile.GetFileFromPathAsync(path);
StorageProviderItemProperty propState = new StorageProviderItemProperty()
{
Id = 3,
Value = "Exclusive",
IconResource = "C:\\path\\icon.ico" // The optional icon to be displayed in the Status column.
};
await StorageProviderItemProperties.SetAsync(storageItem, new StorageProviderItemProperty[] { propState });
Another approach would be implementing IStorageProviderItemPropertySource interface. It returns properties based on your file path.
Cloud Storage Provider implementation. Finally, you will need a complete file system implementation, supplying data for your files/folders placeholders. You can find complete examples in .NET/C# here:
PLEASE PAY ATTENTION: THIS ANSWER IS FOR XP AND VISTA ONLY, IT IS OUTDATED
It can be done on XP using a Column Handler shell extension - see here: http://www.codeproject.com/Articles/3747/Explorer-column-handler-shell-extension-in-C#
However IColumnHandler
is not supported on Vista and up. Here you have to implement PropertyHandler
. See Windows SDK \Samples\winui\Shell\AppShellIntegration\PropertyHandlers
.
Each property is described by property schema XML file. This property schema must be registered with PSRegisterPropertySchema()
. Property handler implements IInitializeWithXXX
, IPropertyStore
and optionally IPropertyStoreCapabilities
. You have to register CLSID
of your implementation for each file extension you want to handle.
Unfortunately, you cannot use AllFileSystemObject
or *
in registration.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With