uygulanmasında sorun yaşamaya çalışırken, Windows'da Python 2.7 altında sembolik bir bağlantının gerçek abspathını döndürmek için bir tür yetenek elde etmenin bir yolunu bulmaya çalışıyorum. (Maya/3ds max gibi çoğu DCC'lerin Python'un bu sürümünü kullanmadığı gibi 3.x'e yükseltme yapamıyorum)Bir readlink() işlevi
sid0 ntfs utils'lerine baktım (islink() işlevi çalışıyor, ancak readlink () işlevi her zaman) nedense benim için boş bir unicode dize döndürür ve yararlı bir komut biriyle beraber maalesef, işe alamadım juntalis ntfs kütüphaneleri(), yayınladı: Ancak
import os, ctypes, struct
from ctypes import windll, wintypes
FSCTL_GET_REPARSE_POINT = 0x900a8
FILE_ATTRIBUTE_READONLY = 0x0001
FILE_ATTRIBUTE_HIDDEN = 0x0002
FILE_ATTRIBUTE_DIRECTORY = 0x0010
FILE_ATTRIBUTE_NORMAL = 0x0080
FILE_ATTRIBUTE_REPARSE_POINT = 0x0400
GENERIC_READ = 0x80000000
GENERIC_WRITE = 0x40000000
OPEN_EXISTING = 3
FILE_READ_ATTRIBUTES = 0x80
FILE_FLAG_OPEN_REPARSE_POINT = 0x00200000
INVALID_HANDLE_VALUE = wintypes.HANDLE(-1).value
INVALID_FILE_ATTRIBUTES = 0xFFFFFFFF
FILE_FLAG_OPEN_REPARSE_POINT = 2097152
FILE_FLAG_BACKUP_SEMANTICS = 33554432
# FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTI
FILE_FLAG_REPARSE_BACKUP = 35651584
GetFileAttributes = windll.kernel32.GetFileAttributesW
_CreateFileW = windll.kernel32.CreateFileW
_DevIoCtl = windll.kernel32.DeviceIoControl
_DevIoCtl.argtypes = [
wintypes.HANDLE, #HANDLE hDevice
wintypes.DWORD, #DWORD dwIoControlCode
wintypes.LPVOID, #LPVOID lpInBuffer
wintypes.DWORD, #DWORD nInBufferSize
wintypes.LPVOID, #LPVOID lpOutBuffer
wintypes.DWORD, #DWORD nOutBufferSize
ctypes.POINTER(wintypes.DWORD), #LPDWORD lpBytesReturned
wintypes.LPVOID] #LPOVERLAPPED lpOverlapped
_DevIoCtl.restype = wintypes.BOOL
def islink(path):
# assert os.path.isdir(path), path
if GetFileAttributes(path) & FILE_ATTRIBUTE_REPARSE_POINT:
return True
else:
return False
def DeviceIoControl(hDevice, ioControlCode, input, output):
# DeviceIoControl Function
# http://msdn.microsoft.com/en-us/library/aa363216(v=vs.85).aspx
if input:
input_size = len(input)
else:
input_size = 0
if isinstance(output, int):
output = ctypes.create_string_buffer(output)
output_size = len(output)
assert isinstance(output, ctypes.Array)
bytesReturned = wintypes.DWORD()
status = _DevIoCtl(hDevice, ioControlCode, input,
input_size, output, output_size, bytesReturned, None)
print "status(%d)" % status
if status != 0:
return output[:bytesReturned.value]
else:
return None
def CreateFile(path, access, sharemode, creation, flags):
return _CreateFileW(path, access, sharemode, None, creation, flags, None)
SymbolicLinkReparseFormat = "LHHHHHHL"
SymbolicLinkReparseSize = struct.calcsize(SymbolicLinkReparseFormat);
def readlink(path):
""" Windows readlink implementation. """
# This wouldn't return true if the file didn't exist, as far as I know.
assert islink(path)
# assert type(path) == unicode
# Open the file correctly depending on the string type.
hfile = CreateFile(path, GENERIC_READ, 0, OPEN_EXISTING,
FILE_FLAG_REPARSE_BACKUP)
# MAXIMUM_REPARSE_DATA_BUFFER_SIZE = 16384 = (16*1024)
buffer = DeviceIoControl(hfile, FSCTL_GET_REPARSE_POINT, None, 16384)
windll.CloseHandle(hfile)
# Minimum possible length (assuming length of the target is bigger than 0)
if not buffer or len(buffer) < 9:
return None
# Only handle SymbolicLinkReparseBuffer
(tag, dataLength, reserver, SubstituteNameOffset, SubstituteNameLength,
PrintNameOffset, PrintNameLength,
Flags) = struct.unpack(SymbolicLinkReparseFormat,
buffer[:SymbolicLinkReparseSize])
print tag, dataLength, reserver, SubstituteNameOffset, SubstituteNameLength
start = SubstituteNameOffset + SymbolicLinkReparseSize
actualPath = buffer[start : start + SubstituteNameLength].decode("utf-16")
# This utf-16 string is null terminated
index = actualPath.find(u"\0")
assert index > 0
if index > 0:
actualPath = actualPath[:index]
if actualPath.startswith(u"?\\"):
return actualPath[2:]
else:
return actualPath
, çoğu zaman denedim çeşitli çözümler bana verdi:
[Hata 126] Belirtilen modül bulunamadı
Böyle ithal cdll olarak malzeme ctypes ithalat ve yapabilir olsam da:
libc = cdll.msvcrt
libc.printf
<_FuncPtr object at 0x0000000002A9F388>
Burada sembolik bağlantıları ile uğraşan üzerinde, bu nedenle herhangi bir işaretçiler Python ve genel olarak ctypes bu bölümünde oldukça yeniyim çok takdir olurdu!
Bu bir cazibe gibi adet OTB çalıştı tanımlar! Bunu yapmaktan hoşlanmıyorum, ancak birileri klişelerle (ve genel olarak Windows API'sı) başlayarak, başlangıçtan başka bir kaynaktan MSDN'den başka herhangi bir kaynak önerir misiniz? Bazı dokümanları anlamakta biraz zorlanıyorum .... Her halükarda, yardım ettiğin için teşekkürler! – sonictk
Cevabımı, CPython’un ['win_readlink'] (https://hg.python.org/cpython/file/ab2c023a9432/Modules/posixmodule.c#l7396) 'ye yakın bir şekilde modelledim, ancak bağlantıları desteklemek için uzattım. – eryksun
[Ctypes öğreticisi] (https://docs.python.org/2/library/ctypes.html#ctypes-tutorial) veya MSDN belgelerinde zor olan bir şey var mı?C programlama için genel olarak [comp.lang.c SSS] 'i gördünüz mü (http://c-faq.com)? – eryksun