다음은 WinSxS 디렉토리에서 CRT를로드하는 예입니다.
actctx.manifest :
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.VC90.CRT"
version="9.0.21022.8"
processorArchitecture="amd64"
publicKeyToken="1fc8b3b9a1e18e3b">
</assemblyIdentity>
</dependentAssembly>
</dependency>
</assembly>
actctx.py :
from ctypes import *
from ctypes.wintypes import *
kernel32 = WinDLL("kernel32", use_last_error=True)
ACTCTX_FLAG_PROCESSOR_ARCHITECTURE_VALID = 0x001
ACTCTX_FLAG_LANGID_VALID = 0x002
ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID = 0x004
ACTCTX_FLAG_RESOURCE_NAME_VALID = 0x008
ACTCTX_FLAG_SET_PROCESS_DEFAULT = 0x010
ACTCTX_FLAG_APPLICATION_NAME_VALID = 0x020
ACTCTX_FLAG_HMODULE_VALID = 0x080
DEACTIVATE_ACTCTX_FLAG_FORCE_EARLY_DEACTIVATION = 1
INVALID_HANDLE_VALUE = HANDLE(-1).value
ULONG_PTR = WPARAM # pointer-sized unsigned integer
class ACTCTX(Structure):
_fields_ = (("cbSize", ULONG),
("dwFlags", DWORD),
("lpSource", LPCWSTR),
("wProcessorArchitecture", USHORT),
("wLangId", LANGID),
("lpAssemblyDirectory", LPCWSTR),
("lpResourceName", LPCWSTR),
("lpApplicationName", LPCWSTR),
("hModule", HMODULE))
def __init__(self, *args, **kwds):
super(ACTCTX, self).__init__(sizeof(self), *args, **kwds)
CreateActCtxW = kernel32.CreateActCtxW
CreateActCtxW.restype = HANDLE
CreateActCtxW.argtypes = (POINTER(ACTCTX),)
ReleaseActCtx = kernel32.ReleaseActCtx
ReleaseActCtx.restype = None
ReleaseActCtx.argtypes = (HANDLE,)
ActivateActCtx = kernel32.ActivateActCtx
ActivateActCtx.argtypes = (HANDLE, POINTER(ULONG_PTR))
DeactivateActCtx = kernel32.DeactivateActCtx
DeactivateActCtx.argtypes = (DWORD, ULONG_PTR)
if __name__ == "__main__":
manifest_path = "actctx.manifest" # keep ref
ctx = ACTCTX(lpSource=manifest_path)
hActCtx = CreateActCtxW(byref(ctx))
if hActCtx == INVALID_HANDLE_VALUE:
raise WinError(get_last_error())
cookie = ULONG_PTR()
if not ActivateActCtx(hActCtx, byref(cookie)):
raise WinError()
msvcr90 = CDLL("msvcr90")
if not DeactivateActCtx(0, cookie):
raise WinError(get_last_error())
ReleaseActCtx(hActCtx)
# show DLL path
hModule = HANDLE(msvcr90._handle)
path = (c_wchar * 260)()
kernel32.GetModuleFileNameW(hModule, path, len(path))
print(path.value)
출력 :
C:\Windows\WinSxS\amd64_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.6161_none_08e61857a83bc251\msvcr90.DLL
,
이것은 VS 2010으로 작성된 Python 3.4.2에서 테스트되었으며 대신 msvcr100.dll과 연결됩니다. 따라서 최소한이 경우에는 활성화 컨텍스트를 설정하는 것이 실제로 필요합니다. 그렇지 않으면 msvcr90.dll로드가 ERROR_MOD_NOT_FOUND
과 함께 실패합니다.
매니페스트를 확장 모듈 인 경우 .pyd에 포함하거나 전용 어셈블리 만 사용할 수 있습니다. ctype 인 경우 매니페스트를 포함시켜 활성화 컨텍스트를 만들 수 있습니다. 나는 그것이 당신이 필요로하는 것이면 후자에 대한 모범을 줄 수 있습니다. – eryksun
확장 모듈이 아니지만 확실히 탐색 할 수있는 경로입니다. .pyd에 매니페스트를 삽입하는 방법에 대한 아이디어가 있습니까? 현재 다음과 같이 ctypes를 사용하여 DLL을 가져옵니다. 'self._lib = ctypes.CDLL (경로)' 여기서 ** 경로 **는 DLL 경로입니다. 당신이 언급 한 예를보고 싶습니다. – skiloup