Create a relative symbolic link in Windows 10 for file copies

7,710

Solution 1

Firstly, we should look at the syntax of options and required parameters generated by entering the mklink command help request, mklink /?:

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.

Currently, it is only possible to imbue relative filepath data within directory symbolic links.

Therefore, we must use the mklink command in conjunction with the ("soft link") mklink command option, /D, like so.

mklink /D . . .

The mklink Target parameter must describe a filepath that includes at least one RELATIVE FILEPATH OPERATOR such as . or .. in conjunction with as many BACKSLASHES (\) as necessitated by the relative hierarchy of (grand-, great-grand-, etc.)parent directories, as well as a "DOUBLE-QUOTED" filepath in any case where one or more whitespace characters are required by a child ABSOLUTE filepath fragment of the link's to-be-concatenated relative mklink Target filepath.

To wit, finishing the command

mklink /D "C:/Test Folder/Link Name With Spaces" . . .

by substituting the mklink Target parameter with

. . . ..\"Target Name With Spaces"

or

. . . "..\Target Name With Spaces"

will create a successfully-concatenated relative filepath target within a link generated at

C:/test foldEr/Link Name With Spaces

and finishing

mklink /D "C:/Test Folder/Test Folder 2/Link Name With Spaces" . . .

with

. . . "..\..\Target Name With Spaces"

or

. . . ..\..\"Target Name With Spaces"

will create a link at

C:/Test Folder/Test Folder 2/Link Name With Spaces.

In all four cases, the final result is a directory symbolic link that points to the directory

C:/TaRget nAme WitH SpacEs,

but which will point to a different location entirely if any of the generated links are ever moved to another directory either by a command such as robocopy or by an application which similarly honors symbolic links.

Solution 2

Three things:

  1. don't use symbolic links unless absolutely necessary, because by default you need to be admin to use them. If you only want to link dirs locally, use Junctions, which are supported by a default restricted user as well.

  2. Try to replace software which doesn't support long Unicode file names, which is possible pretty often. Those long file names are around ever since NTFS and Windows NT, so software simply should support it and many frameworks/runtimes like Java do so out of the box. Software which is intended to copy things around or back things up, which doesn't support long file names, is pretty much broken and surely has other serious limitations as well, especially in case of backups. Think of things like permissions, handling different links and file types properly, Alternate Data Streams etc. One needs to be careful.

  3. The reason for your actual problem seems to be differences in symbolic links vs. Junctions or maybe differences in how the paths provided by the shell are parsed:

C:\Users\tschoening\Documents\test\target>mklink /J "[ target ]" "../src/{[ murks ]}"

Verbindung erstellt für [ target ] <<===>> ../src/{[ murks ]}

C:\Users\tschoening\Documents\test\target>cd "[ target ]"

C:\Users\tschoening\Documents\test\target[ target ]>cd ..

C:\Users\tschoening\Documents\test\target>

As you can see, accessing "[ target ]" this way works, while the following doesn't and generates the same error like you have, only in German:

C:\Users\tschoening\Documents\test\target>mklink /D "[ target ]" "../src/{[ murks ]}"

symbolische Verknüpfung erstellt für [ target ] <<===>> ../src/{[ murks ]}

C:\Users\tschoening\Documents\test\target>cd "[ target ]"

Die Syntax für den Dateinamen, Verzeichnisnamen oder die Datenträgerbezeichnung ist falsch.

C:\Users\tschoening\Documents\test\target>

At least I don't see any other difference than /J vs. /D in my test, but I might be missing something of course. So I suggest repeating your test using Junctions yourself.

Some additional interesting thing I just recognized: Opening the created symlink with the above syntax in cmd.exe and Windows Explorer directly fails, but it succeeds in Link Shell Extension. Have a look at the following screenshot, which is showing the relative path. Clicking "Ziel öffnen" opens a new Windows Explorer folder showing the link target. Looks like Link Shell Extension is interpreting / itself and might provide \ to the underlying Windows API? Something which Windows itself isn't doing, but simply using / as are stated in the link itself, which is wrong for paths. So as @Seth already recognized, the / itself is the problem with the symlinks.

Link Shell Extension showing the tested symlink

Solution 3

You're using the wrong kind of slashes if you want to refer to a parent from the current directory. In that case you need to use a Backslash. Forward slashes work if you only want to reference to children. With an absolute path it doesn't seem to matter.

mkdir C:\temp\example\a
mkdir C:\temp\example\b\c
mklink /D C:\temp\example\a\redirection ..\b

As for the 260 character limit, use an application that handles it instead of looking for an easily broken workaround or shorten your paths.

Share:
7,710

Related videos on Youtube

Stephen Hanson
Author by

Stephen Hanson

Updated on September 18, 2022

Comments

  • Stephen Hanson
    Stephen Hanson almost 2 years

    I'm going to drastically simplify everything I have tried. For exact details, please review the CMD screenshot.

    I want to create a RELATIVE PATH symbolic link named [ RESOURCES ] at the following path:

    C:\Users\crack\Documents\[ GLOBAL ]\[ SOURCE ]\[ INITIATIVES ]\Audio\Music 
    

    That should point to:

    C:\Users\crack\Documents\[ GLOBAL ]\[ SOURCE ]\{[ LONGCHAR REDIRECT ]}
    

    I have been trying mklink /D in cmd as admin, with the following steps.

    1. Navigate to the directory the symbolic link should be created in.

      cd "C:\Users\crack\Documents\[ GLOBAL ]\[ SOURCE ]\[ INITIATIVES ]\Audio\Music"
      
    2. Create the symbolic link.

      mklink /d "[ RESOURCES ]" "../../../{[ LONGCHAR REDIRECT ]}"
      symbolic link created for [ RESOURCES ] <<===>> ../../../{[ LONGCHAR REDIRECT ]}
      

    To the BEST of my understanding, this syntax SHOULD set the link to {[ LONGCHAR REDIRECT ]} in [ SOURCE ] relative to Music but it doesn't!

    The confirmation indicates that the link was created successfully but when I try access the symbolic link I get the following error:

    cd "C:\Users\crack\Documents\[ GLOBAL ]\[ SOURCE ]\[ INITIATIVES ]\Audio\Music\[ RESOURCES ]"
    C:\Users\crack\Documents\[ GLOBAL ]\[ SOURCE ]\[ INITIATIVES ]\Audio\Music\[ RESOURCES ] is not accessible.  
    
    The filename, directory name, or volume label syntax is incorrect.
    

    Am I misunderstanding the use of .. to indicate a parent directory? Again, please feel free to review my multiple experiments via the CMD screenshot. I've tried multiple variations on the relative file path theme, using .., ., and changing around the current directory.

    If mklink will not implement the desired association, please also feel free to recommend a relative file path alternative. I copy the [ GLOBAL ] directory to various drives and backup services, so I need the file-paths truncated to beneath the 260 MAX_PATH limitation via their actual location in the {[ LONGCHAR REDIRECT ]} folder to be reflected across each duplicate location, but I need my working directory to include their virtual locations in the [ RESOURCES ] folder.

    • Seth
      Seth about 7 years
      Your example of the error is actually missing from your screenshot. Using less screaming (all uppercase) names would make it a lot easier on the eyes.
    • Stephen Hanson
      Stephen Hanson about 7 years
      The screenshot is to expand on "everything I have tried". The block-quoted dialog should be more than enough to convey the exact error.
  • Stephen Hanson
    Stephen Hanson about 7 years
    You realize this is Super User, right? Asking me to find one application to use long filenames seems to me like a broken workaround. I'm using multiple applications that rely on compliant 260 MAX_PATH filenames. If you can refer me to documentation that would indicate otherwise, such that suggests that ALL applications will handle an overpathed filename, I might consider switching. Otherwise your suggestion is useless.
  • Stephen Hanson
    Stephen Hanson about 7 years
    Also, I've determined that your suggestion that it was only the slashes to be incomplete. The issue was BOTH slashes, AND the fact that my path name had spaces in it. For the record, the solution, which I JUST discovered, was the following command: C:\Users\crack\Documents[ GLOBAL ][ SOURCE ][ INITIATIVES ]\Audio\Music>mklink /D "[ RESOURCES ]" ..\..\..\"{[ LONGCHAR REDIRECT ]}" I was unaware you could use quotation marks in conjunction with unquoted ".." operators.
  • Thorsten Schöning
    Thorsten Schöning about 7 years
    @Seth Slashes do work for mklink in cmd.exe in general, just tested that: 'mklink /J target "src/murks"' in "src" does work and makes "murks" accessible as target.
  • Thorsten Schöning
    Thorsten Schöning about 7 years
    @StephenHanson Your are only talking of "copying" things and backup purposes and apps like XCOPY or ROBOCOPY are perfectly able to handle long Unicode file names, every reasonable backup app should be as well or it's simply broken. So unless you tell more detailed about the apps you use, suggesting not using them if they don't support long file names is the proper thing to do.
  • Stephen Hanson
    Stephen Hanson about 7 years
    @Thorsten Why is there a MAX_PATH limit if I should just ignore it? I assume it's their to keep the integrity of default applications and working conditions of the Windows operating system. When I start developing my own applications, I'll go to Stack Overflow, and your response will be reasonable. But for everyday "Super Users" circumventing filesystem conventions seems irresponsible.
  • Stephen Hanson
    Stephen Hanson about 7 years
    Also @Thorsten, applications themselves are not the issue, either. Even MANUALLY moving/deleting/modifying files causes issues when the files exceed the MAX_PATH length. I've been through enough headaches.
  • Thorsten Schöning
    Thorsten Schöning about 7 years
    @StephenHanson MAX_PATH is because of backwards compatibility with old legacy apps coming from DOS and non Windows NT only, Microsoft has pretty good docs on that topic: msdn.microsoft.com/en-us/library/windows/desktop/…
  • Stephen Hanson
    Stephen Hanson about 7 years
    I requested symlinks, and expressly stated that I needed RELATIVE file paths. Yes, you missed that symbolic links support RELATIVE file paths, and junctions do NOT. Of course I'm an admin. How else would I even install software? You also seem to miss the fact that exceeding the MAX_PATH causes manual file manipulations to fail. Also, I've answered my own question if you were curious as to the ACTUAL issue. It was a simple enough syntax modification.
  • Thorsten Schöning
    Thorsten Schöning about 7 years
    @StephenHanson I'm using relative file paths in my test. Additionally, Junctions provide the same functionality like true symlinks in your case without the caveat of needing admin perms and in general one of course doesn't need to be an admin the whole time to only install software or manage things one time. In fact, it is simply bad practice to be admin the whole time, that's why using Junctions is preferred where possible.
  • Stephen Hanson
    Stephen Hanson about 7 years
    If your "src" folder is located in your "test" folder, then you are creating a JUNCTION with an ABSOLUTE file path.
  • Thorsten Schöning
    Thorsten Schöning about 7 years
    @StephenHanson It wasn't clear to me that you want to copy the symlink itself with it's relative path around as well. Doesn't change much, your approach still seems to have various caveats: You need to have special permissions everywhere to create your symlink, you need tools being able to handle the symlink differently, you seem to have created a circle in your dir structure if you copy GLOBAL around, which might make some tools fail as well etc.
  • Seth
    Seth about 7 years
    @ThorstenSchöning thanks for pointing that out. I added that information. In this specific case, as he wants to reference a parent, it doesn't work.
  • Seth
    Seth about 7 years
    @StephenHanson so you're actively circumventing/ignoring MAX_PATH already but the suggestion to fix either the applications you're using (by using equivalents that handle longer paths or using a path indicator that doesn't have that limit) or fixing your file structure isn't viable? In addition, yes you need to use quotes for paths that contain spaces. You example already showed that you seem to be aware of it so the MWE only concentrated on the reference. Which wasn't working because you need Backslashes.
  • Seth
    Seth about 7 years
    This is actually wrong. Really the only thing you need to do is to use Backslashes instead of a normal Slash. Using "..\something other" just works fine.
  • Thorsten Schöning
    Thorsten Schöning about 7 years
    @Seth My statement wasn't clear, while Slashes do work in general, they don't for symbolic links, just as you said. I tried with Junctions only, those are handled differently, they're path is resolved differently, while the paths for symlinks are stored for the symlink as text. In those cases you are surely correct, / is most likely never supported.
  • Stephen Hanson
    Stephen Hanson about 7 years
    @Seth, Your original answer to my question was incorrect. mkdir C:\temp\example\a mkdir C:\temp\example\b\c mklink /D C:\temp\example\a\redirection ..\b while reversing the slashes, did NOT include quotes. The quotes are NECESSARY if the file path includes spaces. Obviously, though, because my scenario worked just the same as yours in THIS particular comment thread, it does not matter particularly where they are used, as long as they include the spaces in between them.
  • Seth
    Seth about 7 years
    There is no need to just quote the directory that has the spaces. Make your life easier by just quoting the whole thing. That is what I'm pointing out. Your original comment said that you need to use unquoted .. which is wrong. You probably fixed it in your edit.
  • Stephen Hanson
    Stephen Hanson about 7 years
    @Seth I did, but my assertion was meant to convey that quotes are necessitated by the inclusion of whitespace characters.
  • Stephen Hanson
    Stephen Hanson about 7 years
    @Seth Creating a functioning workaround using built-in commands via a command line is not "circumventing" to the same degree that needlessly over-stepping the MAX_PATH implementation is careless with respect to the creator. Files under my solution are perfectly manageable by manual manipulations implemented by a sole user. Files which exceed MAX_PATH, however, are not. Yours brute-forces a system-wide security and stability measure. Mine simply creates working references to files that are entirely within the operating capacity of anyone developing applications designed to follow the rules.