This is a work in progress, stuff in red are things I’ll elaborate on later
Sync apps like Dropbox work by having a folder on the computer that synchronizes with the cloud. However it is also possible to synchronize files outside this folder by using symbolic or hard links. Links are kind of like more advanced shortcuts that lets you link to content in other areas of the computer. For instance, syncing settings in some application on multiple computers can be done by linking them together via a dropbox-folder.
Creating links usually works by opening the command line and using the “mklink”-command. However it would be nice to be able to do the same thing by right clicking and dragging files as well. In this little project we figure out how to do that by means of “shell extensions”. The DLL-file we create in this project is available on Github, and some simple bash-scripts makes (un)installing easy.
The following post is basically just me rambling on about the things I did and learned (to force myself to rethink the steps). It might not even be educational, and I’ll add all the most relevant links at the bottom.
When starting out I had no previous experience with shell extensions, so researching various approaches to doing this took around 5 hours. I still don’t really know much, but I ended up stealing an example online from the Microsoft dev center, which originally was written to create “hard links” for files. I changed the code to create symbolic links for both files and folders.
Hard vs symbolic links
Based on my understanding, symbolic links and hard links both achieve what I wanted; the ability to sync files or folders from other locations on the drive with Dropbox, Bittorrent Sync or similar. Instead of making copies of the files or moving it altogether you can simply create a link in the folder and the sync software will treat it as a normal file. This also makes it possible to share the same file in multiple sync folders.
Here is how they are different (head to WikiVS for more):
- Hard links can’t link to other volumes/drives, which is a limitation I’d rather not have when making links, since some of my sync folders are located on other drives on occasion.
- Hard links can only link to files, not folders. Symbolic links can link to anything, but will remain as dead links if you remove the original file at some point. Eventually you might need an app to remove broken links if you use this extensively.
- Even if symbolic links only link to folders, sync-applications can still remove files within the original folder. This apparently even happens in write-protected folders! Be careful when sharing folders with other people.
About shell extensions
The elements on the right click context-menu in windows explorer is populated via the registry. Adding stuff to this menu is fairly easy, however drag and drop requires a lot of work by comparison, specifically by registering DLLs that “subscribe” to various file types. Dragging onto a folder requires the following:
Here we see that 7-zip and a Git-app subscribe to directories, as well as some weirdly named app. That’s my app, and it’s named weirdly because that is the app’s “ID”. A similar registry key can be found on “Drive” and “Folder” because you can drag and drop to all those locations. The ID points to this addition to the registry:
Whenever we drag and drop something to a folder or drive, the dll is called. Based on the type of file or number of files, the DLL adds a menu item to the context menu. The DLL-file itself controls this behaviour, my app only adds to the context menu if one file is dragged, when dragging multiple files nothing happens.
DLL things
Write about important additions to dll file (install or remove from registry, Regsvr32)
Other things I tried
Initially I tried to add a context item that called a java “jar”-file that would create symbolic links. Adding symlinks in Java was attempted by using
Runtime.exec("cmd /c mklink linkname path_to_file");
Sadly since I wanted drag and drop I didn’t bother figuring out how to easily run java code with dragdrophandlers.
I also tried using Python but ended up running into the same problem. At least creating symbolic links is simple with Python 3 by writing
import os
os.mklink(filename, path_to_file)
I also learned that it’s possible to make exe-files easily using py2exe, but as mentioned previously we need a DLL file with extension handlers to do anything worthwhile.
Sources
http://www.codeproject.com/Articles/449/The-Complete-Idiots-Guide-to-Writing-Shell-Exten
http://code.msdn.microsoft.com/windowsapps/CppShellExtDragDropHandler-bbdb6bac
http://msdn.microsoft.com/en-us/library/bb776881.aspx%23dragdrop
http://msdn.microsoft.com/en-us/library/windows/desktop/bb776778%28v=vs.85%29.aspx