Python symbolic links on windows do not show up
Asked Answered
G

0

0

I have seen answers about how to create symbolic links on Windows using Python (I am on Win 7). However the links does not show up in the system for some reason even though the call claim success. Am I missing something obvious ?

>>> import ctypes
>>> kdll = ctypes.windll.LoadLibrary("kernel32.dll")
>>> kdll.CreateSymbolicLinkA("C:\\testlink", "C:\\existing_dir", 1)
1
>>> ctypes.WinError()
WindowsError(0, 'The operation completed successfully.')
>>> kdll.CreateSymbolicLinkA("C:\\testlink", "C:\\existing_dir", 1)
0
>>> ctypes.WinError()
WindowsError(0, 'Cannot create a file when that file already exists.')
>>> os.path.exists("C:\\testlink")
False
>>> os.path.islink("C:\\testlink")
False

Why does the calls to the windows api think that that the link was created when python can't see it with os.path.exist ? And neither can I see the link in the file explorer or using dir in cmd on the Windows box. So where did the link go ?

Gamophyllous answered 10/3, 2016 at 10:44 Comment(8)
if the link is broken, then it is not exists, but islink is true, because the file is there. and there is os.symlink function, just for thatOptional
os.path.islink also reports False. I am on Python 2.7, and os.symlink say it's available only on Unix.Gamophyllous
However I see I can work around this by instead using subprocess and calling mklink directly from the shell like call(['mklink', 'C:\\testlink', 'C:\\existing_dir'], shell=True). Still that does not explain why I see the behavior above - so I am still curious.Gamophyllous
It should work if you have SeCreateSymbolicLinkPrivilege, and it says that it did work. Did you try creating the link in another directory, such as C:\Temp? If you're using 32-bit Python, maybe it was created in %LOCALAPPDATA%\VirtualStore.Cordeiro
sorry, my bad. I didn't realize python2 does not support symlink on windows. It does support on python3 though. docs.python.org/3/library/os.html?highlight=symlink#os.symlinkOptional
@eryksun I see nothing VirtualStore. I ran the above commands with admin rights, without it the first link command fails.Gamophyllous
Your mklink command creates a broken link. You need mklink /d to link to a directory. Trying to open a file as a directory fails. This is checked in the NtOpenFile system call before the path is reparsed to follow the symbolic link, so the actual link itself needs to be created as a directory. That's why your CreateSymbolicLink call uses the flag SYMBOLIC_LINK_FLAG_DIRECTORY (1).Cordeiro
That was a typo in my comment - the workaround worked, but not the original approach.Gamophyllous

© 2022 - 2024 — McMap. All rights reserved.