我从python网站下载了python 2.7.1并将其安装到了windows。在尝试对文件进行符号链接时,我发现它不受支持。
然而,我找到this issue,并看到它已修复。这会被实施,如果是这样的话?我正在运行Windows Vista。
答案 0 :(得分:26)
有一种方法可以解决这个问题,在你的python环境启动时修补 os 模块。
创建符号链接的功能已经可以从Windows API获得,您只需要调用它。
在python启动期间,尝试在site-packages directory上导入名为 sitecustomize.py 的模块。我们将使用此钩子将我们的函数附加到os模块。
将此代码放在sitecustomize.py:
文件中import os
__CSL = None
def symlink(source, link_name):
'''symlink(source, link_name)
Creates a symbolic link pointing to source named link_name'''
global __CSL
if __CSL is None:
import ctypes
csl = ctypes.windll.kernel32.CreateSymbolicLinkW
csl.argtypes = (ctypes.c_wchar_p, ctypes.c_wchar_p, ctypes.c_uint32)
csl.restype = ctypes.c_ubyte
__CSL = csl
flags = 0
if source is not None and os.path.isdir(source):
flags = 1
if __CSL(link_name, source, flags) == 0:
raise ctypes.WinError()
os.symlink = symlink
您的Python过程需要以启用“创建符号链接”权限启动,这不是Python问题,声称使用此Windows API的每个程序都需要它。这可以通过提升cmd.exe
运行Python解释器来完成。如果您的Windows版本附带了必需的组策略编辑器(gpedit.msc
),则更好的选择是将权限授予用户。请参见下面的截图。您可以调整该值以包括任何用户或安全组需要此类权限,而不会影响管理帐户的安全性。
注意:来自here
的代码段答案 1 :(得分:20)
就像Fernando Macedo的回答一样,但IMO的侵入性较小:
def symlink(source, link_name):
import os
os_symlink = getattr(os, "symlink", None)
if callable(os_symlink):
os_symlink(source, link_name)
else:
import ctypes
csl = ctypes.windll.kernel32.CreateSymbolicLinkW
csl.argtypes = (ctypes.c_wchar_p, ctypes.c_wchar_p, ctypes.c_uint32)
csl.restype = ctypes.c_ubyte
flags = 1 if os.path.isdir(source) else 0
if csl(link_name, source, flags) == 0:
raise ctypes.WinError()
答案 2 :(得分:10)
与Gian Marco Gherardi answer一样,但在Windows上定义os.symlink
,以便您的代码可以安全地在Windows和Linux上运行:
import os
os_symlink = getattr(os, "symlink", None)
if callable(os_symlink):
pass
else:
def symlink_ms(source, link_name):
import ctypes
csl = ctypes.windll.kernel32.CreateSymbolicLinkW
csl.argtypes = (ctypes.c_wchar_p, ctypes.c_wchar_p, ctypes.c_uint32)
csl.restype = ctypes.c_ubyte
flags = 1 if os.path.isdir(source) else 0
if csl(link_name, source, flags) == 0:
raise ctypes.WinError()
os.symlink = symlink_ms
如果您以管理员身份运行脚本,一切都很好,如果您想以用户身份运行它 - 您必须grant python a permission to make symlinks - 这只能在windows vista + ultimate或professional下使用。
修改强>:
Gian Marco Gherardi answer创建了一个指向unix路径的链接:like/this
但它不起作用。解决方法是source.replace('/', '\\')
:
# symlink support under windows:
import os
os_symlink = getattr(os, "symlink", None)
if callable(os_symlink):
pass
else:
def symlink_ms(source, link_name):
import ctypes
csl = ctypes.windll.kernel32.CreateSymbolicLinkW
csl.argtypes = (ctypes.c_wchar_p, ctypes.c_wchar_p, ctypes.c_uint32)
csl.restype = ctypes.c_ubyte
flags = 1 if os.path.isdir(source) else 0
if csl(link_name, source.replace('/', '\\'), flags) == 0:
raise ctypes.WinError()
os.symlink = symlink_ms
另一种方法是使用window的vista + mklink
实用程序。但使用此实用程序需要相同的权限。仍然:
# symlink support under windows:
import os
os_symlink = getattr(os, "symlink", None)
if callable(os_symlink):
pass
else:
def symlink_ms(source, link_name):
os.system("mklink {link} {target}".format(
link = link_name,
target = source.replace('/', '\\')))
os.symlink = symlink_ms
编辑2 :
这就是我最终使用的内容:如果用户有特权,这个脚本会在windows下创建一个链接,否则它就不会建立链接:
import os
if os.name == "nt":
def symlink_ms(source, link_name):
import ctypes
csl = ctypes.windll.kernel32.CreateSymbolicLinkW
csl.argtypes = (ctypes.c_wchar_p, ctypes.c_wchar_p, ctypes.c_uint32)
csl.restype = ctypes.c_ubyte
flags = 1 if os.path.isdir(source) else 0
try:
if csl(link_name, source.replace('/', '\\'), flags) == 0:
raise ctypes.WinError()
except:
pass
os.symlink = symlink_ms