Sunday, January 20, 2013


Here I am, late to the party - Microsoft launched mklink back in Vista days, but somehow I managed to miss the fireworks. There must have been fireworks, man! MKLINK will save your so many times now that you know it exists, that you will wonder just how you made it before.
The real thing about MKLINK is not MKLINK itself - it's just a command-line utility to create file system links. But: file system links! That is the deal. You see folks, I have some *nix background. During college I worked on that OS a number of times, and later on I was part of some projects that had back-ends hosted in a fine Red Hat rig. In any case, I always missed two things about *nix. The first one was the command line shell (bash) along with all the command line utilities and the second one is file system links.
"Just what are file system links?” you may be asking. Links resemble Windows shortcuts. In fact, it works very similarly to them, but there is a large difference inside: Intel. Oh, wait, that’s not it. With file system links, you can create entries in the file system that point to other entries that are already there.
There you go, the most obtuse definition I have ever written. Let us try again. When you create a link, you point that link to something. The operating system then creates a "fake" file on the system that actually is just another path to access that file. To any application and, in fact, even in the Windows Explorer, they pretty much like the file they are pointing to. And yeah, you can do that with folders as well.
Just one more thing to consider when talking about links: they can be either hard links or symbolic links.
With symbolic links, you essentially get the same thing as shortcuts. The link points to the actual record which points to the file. This means that if you change something like access permissions for the first file, it will affect the link. Symbolic links can also get "broken", in case you delete the original file that points to the disk.

Symbolic Links

With hard links, there are no differences between the original entry and the link entry (see picture). The operating system effectively duplicates the record that points to the file on the disk, which results in you having two files that are actually the same (the file is removed only after you delete both entries). Hard links are more powerful but have lot of restrictions; you cannot hard link to a directory, and you cannot have hard link between drives.

Hard Links
Ufs! I hope I made some sense. In any case, if you still don't get it, check the Wikipedia entry. For now, let's focus on MKLINK. 


There are many cases where you might want to use links. I will use a complex scenario, but one that bugged me for a while.
I once worked on a project in which my team was building a .NET application. The application was build in many layers, and the team decided it was best to have distinct solutions for stuff like back-end or front-end code. So we had at least three solutions that produced different DLLs that where necessary to actually run the application. That may have made managing multiple work streams easier, but it was hell to get stuff to compile -- we had to get a number of DLLs out of the Debug or Release folders and then copy then over to the same location, and then start the application.
Of course, we automated the copy process as part of the build process, but that was not perfect: for instance, if I made a "clean" in the solution, the DLLs wouldn't be erased from the "common folder" where we copied everything.
This let to infrequent but worrisome problems, for instance, the COPY command could fail and then the application would be ran with out-of-date DLLs. It also meant a copy step after build, one that got steadily slower as the application grew.
We could have used links to solve at least part of those problems. All I had to do was to make a small script that, whenever activated, would clean the "common folder" and then create there a symbolic link pointing to the DLL in the Debug folder of each solution. This step did not had to occur at each compilation, as the symbolic links would always point to the new file. If I cleaned the solution, all DLLs in the Debug or Release folder would be erased and the links would be broken, so I wouldn't be able to run the application with outdated DLLs.
Another interesting scenario is sharing a file between two applications: maybe it is a large, read-only file, like a picture or even a library or executable. Instead of having the duplicate residing in your machine, using twice the space, you can use MKLINK to create a hard link, which will result in two files that use the data on the disk, saving the space.
One final example: Let us say that you want to synchronize your folders using a tool such as Dropbox, but pains you to have all your neatly organized files stashed in the same, outlandish folder, like C:\Dropbox. With symbolic links, you can organize a directory tree in the Dropbox root folder and then create a bunch of “symlinks” to those folders in your computer, like this:
"C:\Users\bruno.brant\Project Data" à "C:\Dropbox\ProjectData"
"C:\Users\bruno.brant\Desktop\Downloaded Applications" à "C:\Dropbox\Downloads"

Notice that the name of the links is not necessarily the same name as the folder it points to.
This goes a long way into getting stuff organized. Double clicking any of those folders will take you to the Dropbox folder and it will be completely transparent to your applications.
The tool syntax can be recovered simply by typing mklink /? in your oldie CMD, like this:
C:\> mklink /?
Creates a symbolic link.

MKLINK [[/D] | [/H] | [/J]] Link Target
        /D      Creates a directory symbolic link.  Default is a file
                symbolic link.
        /H      Creates a hard link instead of a symbolic link.
        /J      Creates a Directory Junction.
        Link    specifies the new symbolic link name.
        Target  specifies the path (relative or absolute) that the new link
                refers to.
Let's say you want to create a new link that implements the mapping I talked about in the final example above, pointing from my downloaded applications folder to Dropbox. All I'd do is:
C:\> mklink /D "Users\bruno.brant\Project Data" "C:\Dropbox\ProjectData"

This simple command will result in a new folder in your Users directory which, when opened, always shows you the exact content in the dropbox folder.
There are a few restrictions to links, as there should, considering they are not really files.
You cannot use hard links to points to directories. As I said before, hard links are "duplicates" of files, and the main idea is that you get two different entries which points to the same location in the disk. However, directories do not point to places in the disk, they only point to files. If I duplicate a directory, what happens if one creates a file one of the directories? The duplicate would have to be updated, but then this means a relationship between the two... which is exactly what symbolic links are!
You cannot use hard links to point to a file in another partition or unit. The reason is that if the file entry belongs to one partition, its data have to be in that partition. It would be illogic to expect that a file in unit C is actually stored in unit D or a removable drive. However, you can use symbolic links for that, since Windows already expect that symbolic files do not represent actual files but point to them, in a fashion.

No comments :

Post a Comment