Python 2.7에서 Windows의 심볼릭 링크의 진정한 절대 경로를 반환 할 수있는 능력을 얻는 방법을 찾으려고 노력했습니다. (Maya/3ds max와 같은 대부분의 DCC는 해당 버전의 Python을 사용하지 않기 때문에 3.x로 업그레이드 할 수 없습니다)
나는 sid0 ntfs 유틸리티 (islink () 함수가 작동하지만 readlink () 함수는 항상 어떤 이유로 든 빈 유니 코드 문자열을 반환)를 보았습니다)와 juntalis ntfs libs를 보았습니다 (불행히도, 나는 다른 사람이 게시 한 유용한 스크립트와 함께 작동하지 않습니다.
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
그러나 내가 시도한 다양한 솔루션은 대부분 나에게 다음을 제공합니다.
[오류 126] 지정된 모듈을 찾을 수 없습니다
ctypes를 가져오고 cdll 가져 오기와 같은 작업을 수행 할 수는 있지만 :
libc = cdll.msvcrt
libc.printf
<_FuncPtr object at 0x0000000002A9F388>
일반적으로 파이썬과 ctypes의이 부분에 익숙하지 않기 때문에 여기에서 심볼릭 링크를 다루는 것에 대한 조언은 대단히 감사하겠습니다!
- 답변 # 1
- 답변 # 2
이것은 Tcl에서
file readlink
로 구현됩니다. 그리고 약간의 차이가있는 것처럼 보이기 때문에 이것을 읽을 가치가 있습니다. 와이즈 비즈 함수 호출WinReadLinkDirectory
NativeReadReparse
를 읽으려면 그러나 이것은REPARSE_DATA_BUFFER
에 다른 플래그를 사용합니다. 기능. 또한 버퍼 크기가 다르다고 생각하며 Win32 호출의 구조 크기는 종종 사용되는 API 버전을 감지하는 데 사용되므로 크기를 올바른 값 (또는 가능한 동일한 값)으로 설정하는 것이 좋습니다 Tcl 구현))Tcl 지원에 대한 의미를 보여 드리기 위해 :
CreateFile
C:\>dir Directory of C:\ 22/09/2014 14:29 <JUNCTION> Code [C:\src] ... C:\>tclsh % file readlink Code C:\src
관련 자료
- discord.py - 이 코드에 문제가 있습니다
- python - N이 배열이고 N [1] [i]가 for 루프 안에 있으면 N [1] [i]는 무엇을합니까? 이해하는 데 문제가 있습니다
- python - Windows cmd에서 간단한 HelloWorldpy 파일을 실행하는 데 문제가 있습니다
- reactjs - React에서 렌더링 된 구성 요소를 변환하는 함수를 배치 할 위치를 찾는 데 어려움을 겪고 있습니다
- html - Carousel Bootstrap에서 일반 이미지와 이미지를 반응 형으로 만드는 데 문제가 있습니다
- python - 수업 코드에 문제가 있습니다
- python - 2 개의 타임 스탬프 사이의 기간을 가져 오는 데 문제가 있음
- python - 타임 스탬프를 읽을 수있는 문자열로 변환하는 데 문제가 있습니다
- c++ - equals 연산자에 문제가 있습니다 종료 코드 11로 마무리
- r - for 루프에서 벡터를 채우는 데 문제가 있습니다
- loops - R의 함수를 통해 반복되는 문제
- c# - UseInMemoryDatabase ASPNET Core 31에 문제가 있음
- search - Julia에서 Matlab의 "찾기"기능을 효율적으로 구현
- javascript - React Native iOS/Android에서 날짜 범위 필터를 구현하는 데 문제가 있음
- python - pyspark 데이터 프레임에서 최대 값을 검색하는 데 문제가 있습니다
- XML 태그를 순서대로 반복하는 데 문제가있는 Python ElementTree
- python - Django 내에서 urlpy를 변경하는 데 문제가 있습니다
- reactjs - react-simple-file-upload를 사용하여 이미지를 표시하는 데 문제가 있습니다
- Cypress - 사이프러스 - cyintercept를 사용하여 요청에 대해 주장하는 데 문제가 있습니다 '주체에 요청이 없기 때문에 cyits () 오류가 발생했습니다'
- java - 메인 메소드에서 비 정적 메소드를 호출하는 데 문제가 있지만 유사한 질문과 기사를 읽은 후에도 여전히 솔루션을 이해하지 못합니다
ERROR_MOD_NOT_FOUND
(126)은windll.CloseHandle(hfile)
로 인한 것 같습니다 "closehandle.dll"를로드하려고합니다.kernel32
가 없습니다 .다음은 정션 및 심볼릭 링크를 처리하는 대체 구현입니다.
타입 정의
기능
예