我从python网站下载了python 2.7.1,并将它安装到了windows。尝试符号链接文件时,我发现它不受支持。Windows中的OS.symlink支持
但是,我发现this issue,并看到它是固定的。这是否会实施,如果是的话?我正在运行Windows Vista。
我从python网站下载了python 2.7.1,并将它安装到了windows。尝试符号链接文件时,我发现它不受支持。Windows中的OS.symlink支持
但是,我发现this issue,并看到它是固定的。这是否会实施,如果是的话?我正在运行Windows Vista。
有一种方法可以解决这个问题,在您的python环境启动时修补模块os。
创建符号链接的功能已经可以从Windows API获得,您只需要调用它即可。
在python的启动过程中,尝试导入名为sitecustomize.py的模块,在site-packages directory上。我们将使用这个钩子将我们的功能附加到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
像费尔南多·马塞答案片断,但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()
像吉安·马尔科GHERARDI answer但定义os.symlink
在Windows上,以便您的代码可以安全地在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下运行。
编辑:
吉安·马尔科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
另一种方法是使用窗口的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下一个链接,如果用户有privilage这样做,否则它只是没有一个链接:
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
我明白如果遇到权限问题,该函数被设计为noop,但我不明白为什么ctypes.WinError异常会被引发,如果它总是被异常处理程序吞下?这是一个占位符,使开发人员可以选择与异常做不同的事情,还是我在这里错过了一个微妙的东西? – 2016-08-16 15:27:01
@WilliamPayne:据我所知,它是由于它具有足够的权限而产生链接,但是在'csl(link_name,source.replace('/','\\'),flags)= = 0' - 在这种情况下,它也会建立链接。所以一切正常,我不明白为什么'WinError'。所以我只是压制了这个错误。 – Adobe 2016-08-16 15:43:47
尝试Python 3.2。 – Blender 2011-06-07 02:53:20
添加作为答案,我会标记为正确的。 – xaav 2011-06-07 14:58:24
@xaav,因为Blender的答案已被删除(我不知道为什么),您能否认可我的答案,将其标记为正确,因为它显示了问题的解决方法?谢谢! – 2014-12-18 14:04:38