在Windows下使用Python 2.7有没有办法检查文件夹是否是任何联结点的目标?如果是这样,找到哪个符号链接会导致它?
例如,在dos shell中使用mklink
创建一个连接点C:\>mklink /J C:\junction C:\Users
Junction created for C:\junction <<===>> C:\Users
并且在python中(假设没有事先知道这个连接存在)测试“C:\ Users”如果它是任何连接点的目标,返回一个符号链接列表,如果为True,在这种情况下:['C: \结']
答案 0 :(得分:1)
这是我使用名为Windows directory walk using ctypes的ActiveState配方中的一些代码放在一起的东西。与使用win32 FindFirstFile
和FindNextFile
函数相比,可能有更直接的方法,但这似乎适用于我的有限测试。
import os
import sys
import ctypes
from ctypes import Structure
from ctypes import byref
import ctypes.wintypes as wintypes
from ctypes import addressof
FILE_ATTRIBUTE_DIRECTORY = 16 # (0x10)
FILE_ATTRIBUTE_REPARSE_POINT = 1024 # (0x400)
MAX_PATH = 260
GetLastError = ctypes.windll.kernel32.GetLastError
class FILETIME(Structure):
_fields_ = [("dwLowDateTime", wintypes.DWORD),
("dwHighDateTime", wintypes.DWORD)]
class WIN32_FIND_DATAW(Structure):
_fields_ = [("dwFileAttributes", wintypes.DWORD),
("ftCreationTime", FILETIME),
("ftLastAccessTime", FILETIME),
("ftLastWriteTime", FILETIME),
("nFileSizeHigh", wintypes.DWORD),
("nFileSizeLow", wintypes.DWORD),
("dwReserved0", wintypes.DWORD),
("dwReserved1", wintypes.DWORD),
("cFileName", wintypes.WCHAR * MAX_PATH),
("cAlternateFileName", wintypes.WCHAR * 20)]
def find_junctions(folder):
""" Return a list of subdirectories in folder which are junction points """
if not os.path.isdir(folder):
return False
folder = unicode(folder)
if not folder.startswith(u'\\\\?\\'):
if folder.startswith(u'\\\\'):
# network drive
folder = u'\\\\?\\UNC' + folder[1:]
else:
# local drive
folder = u'\\\\?\\' + folder
junction_points = []
data = WIN32_FIND_DATAW()
h = ctypes.windll.kernel32.FindFirstFileW(os.path.join(folder, u'*'),
byref(data))
last_error = ctypes.windll.kernel32.GetLastError()
if h < 0:
ctypes.windll.kernel32.FindClose(h)
if not sys.stderr.isatty():
print >> sys.stderr, ('Failed to find first file %s' %
os.path.join(folder, u'*'))
if last_error != 5: # access denied.
raise WindowsError('FindFirstFileW %s, Error: %d' %
(folder, ctypes.windll.kernel32.GetLastError()))
return []
if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY and
data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT):
if data.cFileName not in (u'.', u'..'):
junction_points.append(data.cFileName[:])
try:
while ctypes.windll.kernel32.FindNextFileW(h, byref(data)):
if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY and
data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT):
if data.cFileName not in (u'.', u'..'):
junction_points.append(data.cFileName[:])
except WindowsError as e:
if not sys.stderr.isatty():
print >> sys.stderr, (
'Failed to find next file %s, handle %d, buff addr: 0x%x' %
(os.path.join(folder, u'*'), h, addressof(data)))
ctypes.windll.kernel32.FindClose(h)
return junction_points
def is_junction_point(folder):
dirpath, folder = os.path.split(os.path.abspath(folder))
return unicode(folder) in find_junctions(dirpath)
答案 1 :(得分:0)
看起来这很难有效,但您可以扫描卷上的所有现有交接点(请参阅http://en.wikipedia.org/wiki/NTFS_junction_point“获取交接点列表”)。然后,您必须将这些与实际指向的内容相关联。目录本身并不指向现有的联结,因此您可以非常有限地找到这些联结。