Source repository: https://github.com/aelyo-softworks/AmalgaDrive
A WPF application shell folder.
Demonstrates the File On-Demand feature. The Visual Studio solution has
AmalgaDrive.DavServer: A zero-dependency custom WebDAV Server library that serves a local
directory as a WebDAV directory resource. Exposes a custom REST / JSON API. Written
for .NET core.
AmalgaDrive.DavServerSite: A sample WebDAV site. It’s merely a host for the AmalgaDrive.DavServer
library. Written with ASP.NET core.
AmalgaDrive: a WPF
Shell Namespace Extension that amalgamates various Cloud drives.
AmalgaDrive has been written to connect to
implementations of the ShellBoost’s IRemoteFileSystem interface
(described in the Files On-Demand support
chapter). The sample currently contains only one implementation of IRemoteFileSystem
which is an implementation that relies on a WebDAV server for the “remote” file
system. The implementation is located in the DavFileSystem.cs and DavResource.cs
files. This DavFileSystem implementation has been written to connect to
any WebDAV service, local, or on the internet. It has been successfully tested
to work with AmalgaDrive.DavServerSite, www.box.com and www.cloudme.com WebDAV implementations.
Other implementation of IRemoteFileSystem
could be added to enable AmalgaDrive to use other cloud “drive” systems
(Google, Amazon, etc.).
AmalgaDrive.DavServerSite is not mandatory
to run to test AmalgaDrive since AmalgaDrive supports by default other WebDAV
services such as www.box.com
if you want to test it, it has no UI, it’s an API-only site.
What it does is serve an existing folder on
your hard disk as a WebDAV directory resource. The served folder can be
configured in the appsettings.json file in the project. It looks like
Just change the RootPath value and
restart the server to serve another folder on your disk.
By default, it runs on http://localhost:61786/
When you start AmalgaDrive, open the “File
/ Add a Cloud Drive…” menu item, then enter login information and press OK.
This is an example with the www.box.com service:
This is an example with the
AmaldaDrive.DavServerSite sample (there is no authentication for demonstration
Once you’ve added at least one Cloud Drive,
you should see something like this. You can add any number of drives. Right
now, remember that the program only supports WebDav-type cloud drives.
Synchronization should happen automatically
in 300 seconds (by default). If you want to force synchronization, just press
the green refresh button. Note there is a menu item in the Tools menu that
allows you to see sync logs.
Let’s suppose you’re using a www.box.com account
with the following files in your web personal storage:
If you want to see the drive like a
standard Windows directory path, click on the AmalgaDrive UI first
orange button (tooltip says “Open Path”). You should see something like this in
As you see it looks like OneDrive, with a Status
column that represents the offline availability of each shell item. Nothing is
stored locally yet, as the little blue cloud icon means “Available when
online”. If you double-click on one file for example the AboutWindow.xaml.cs
sample file, Windows will ask AmalgaDrive to download the file, once downloaded
(in the background, the process is completely transparent to the end-user), the
file will open (with your configured editor for .cs files in this case). At the
same time, the shell will automatically update the icon to a little green
circle check that means “Available on this device”.
Note that for this to work, we don’t use
any Shell Namespace Extension. But you can also view the same directory
hierarchy using a ShellBoost Namespace Extension embedded into AmalgaDrive.
Click on the AmalgaDrive UI second orange button (tooltip says
“Open Extension”). You should see something like this in Windows Explorer:
As you see we have the same Status
icon column in our namespace extension. The column is added to a folder with
public OnDemandRootFolder(OnDemandShellFolderServer server, ShellItemIdList idList, DirectoryInfo info)
: base(idList, info)
if (server == null)
throw new ArgumentNullException(nameof(server));
if (info == null)
throw new ArgumentNullException(nameof(info));
Server = server;
// since this is a FileSystem oriented NSE, we let base properties pass through
ReadPropertiesFromShell = true;
/// We just add the sync status column.
And each item declares its state like this:
public override bool TryGetPropertyValue(PropertyKey key, out object value)
// this property is asked by the Shell to display the sync status icon
if (key == Props.System.StorageProviderUIStatus)
value = GetSyncState(this);
return base.TryGetPropertyValue(key, out value);
private static MemoryPropertyStore GetSyncState(ShellItem item)
var ms = new MemoryPropertyStore();
ms.SetValue(Props.System.PropList.StatusIcons, "prop:" + Props.System.StorageProviderState.CanonicalName);
// read the sync state from the shell
// it works because we have set ReadPropertiesFromShell = true as a passthrough
var state = item.GetPropertyValue(Props.System.StorageProviderState, 0);