- 使用
ctypes库(推荐,无需安装第三方库):ctypes是 Python 的标准库,允许您直接调用 DLL 中的函数,这是最基础、最灵活的方法。 - 使用
pywin32库(功能更强大,需要安装):pywin32是一个第三方库,它为 Windows API 提供了更 Pythonic 的封装,使用起来可能更方便,尤其是在处理 COM 对象和复杂结构时。
下面我将详细介绍这两种方法,并提供完整的代码示例。

使用 ctypes 库(标准库)
这是最直接的方法,我们不需要安装任何额外的包。
步骤 1:导入 ctypes 并定义函数
CreateFile 函数位于 kernel32.dll 中,我们需要告诉 Python 这个函数的原型(参数类型和返回值类型)。
import ctypes
from ctypes import wintypes
# 加载 kernel32.dll
kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
# 定义 CreateFile 函数的参数和返回值类型
# Windows API 文档: https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea
kernel32.CreateFileW.argtypes = [
wintypes.LPCWSTR, # lpFileName
wintypes.DWORD, # dwDesiredAccess
wintypes.DWORD, # dwShareMode
wintypes.LPVOID, # lpSecurityAttributes
wintypes.DWORD, # dwCreationDisposition
wintypes.DWORD, # dwFlagsAndAttributes
wintypes.HANDLE # hTemplateFile
]
kernel32.CreateFileW.restype = wintypes.HANDLE # 返回一个句柄 (HANDLE)
重要提示:
- 我们使用
CreateFileW而不是CreateFileA。W版本表示 "Wide",使用 Unicode (UTF-16) 字符串,可以更好地处理非英文字符。A版本使用 ANSI 字符串。 argtypes定义了每个参数的类型。restype定义了函数返回值的类型。CreateFile返回一个HANDLE(句柄),在ctypes中通常用wintypes.HANDLE表示,它本质上是一个无符号整数。
步骤 2:定义常量
CreateFile 的参数中有多个标志位常量,我们需要从 Windows API 中导入它们。

# --- 常量定义 --- # Desired Access (dwDesiredAccess) GENERIC_READ = 0x80000000 GENERIC_WRITE = 0x40000000 GENERIC_EXECUTE = 0x20000000 GENERIC_ALL = 0x10000000 # Share Mode (dwShareMode) FILE_SHARE_READ = 0x00000001 FILE_SHARE_WRITE = 0x00000002 FILE_SHARE_DELETE = 0x00000004 # Creation Disposition (dwCreationDisposition) CREATE_NEW = 1 CREATE_ALWAYS = 2 OPEN_EXISTING = 3 OPEN_ALWAYS = 4 TRUNCATE_EXISTING = 5 # Flags and Attributes (dwFlagsAndAttributes) FILE_ATTRIBUTE_NORMAL = 0x80 FILE_FLAG_OVERLAPPED = 0x40000000
步骤 3:调用函数并处理结果
现在我们可以调用 CreateFile 来创建或打开一个文件。
def create_file_with_ctypes(file_path):
"""
使用 ctypes 调用 CreateFile 创建或打开文件。
"""
# 打开一个已存在的文件进行读写
# 如果文件不存在,会失败
handle = kernel32.CreateFileW(
file_path,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ, # 允许其他进程读取
None, # 默认安全属性
OPEN_EXISTING, # 必须已存在
FILE_ATTRIBUTE_NORMAL,
None # 无模板文件
)
# 检查调用是否成功
if handle == wintypes.HANDLE(-1).value: # INVALID_HANDLE_VALUE
error_code = ctypes.get_last_error()
print(f"创建文件失败!错误代码: {error_code}")
# 可以使用 FormatMessage 获取错误信息的文本描述
return None
else:
print(f"文件打开成功!句柄: {handle}")
# 使用完毕后,必须关闭句柄!
kernel32.CloseHandle(handle)
return handle
# --- 示例用法 ---
if __name__ == "__main__":
# 假设我们有一个 test.txt 文件
file_to_open = "C:\\temp\\test.txt"
# 如果文件不存在,先创建一个
import os
os.makedirs("C:\\temp", exist_ok=True)
with open(file_to_open, "w") as f:
f.write("Hello, CreateFile!")
print("--- 尝试打开一个已存在的文件 ---")
create_file_with_ctypes(file_to_open)
print("\n--- 尝试创建一个新文件 (CREATE_ALWAYS) ---")
new_file_path = "C:\\temp\\newfile.txt"
handle = kernel32.CreateFileW(
new_file_path,
GENERIC_WRITE,
0, # 不共享
None,
CREATE_ALWAYS, # 如果存在则覆盖,不存在则创建
FILE_ATTRIBUTE_NORMAL,
None
)
if handle != wintypes.HANDLE(-1).value:
print(f"文件创建/覆盖成功!句柄: {handle}")
kernel32.CloseHandle(handle)
else:
print("文件创建失败!")
print("\n--- 尝试打开一个不存在的文件 (OPEN_EXISTING) ---")
non_existent_file = "C:\\temp\\non_existent.txt"
create_file_with_ctypes(non_existent_file)
使用 pywin32 库
pywin32 将 Windows API 的类型和函数映射到了 Python 的原生类型,使用起来更直观。
步骤 1:安装 pywin32
你需要安装这个库,打开命令行(CMD 或 PowerShell)并运行:
pip install pywin32
步骤 2:调用函数
pywin32 已经为你定义好了所有的常量和函数原型。
import win32file
import winerror
def create_file_with_pywin32(file_path):
"""
使用 pywin32 调用 CreateFile 创建或打开文件。
"""
# 打开一个已存在的文件进行读写
try:
# pywin32 的 CreateFile 直接返回句柄,如果失败会抛出异常
handle = win32file.CreateFile(
file_path,
win32file.GENERIC_READ | win32file.GENERIC_WRITE,
win32file.FILE_SHARE_READ,
None,
win32file.OPEN_EXISTING,
win32file.FILE_ATTRIBUTE_NORMAL,
None
)
print(f"文件打开成功!句柄: {handle}")
# 使用完毕后,必须关闭句柄!
win32file.CloseHandle(handle)
return handle
except pywintypes.error as e:
# pywintypes.error 是一个包含 (error_code, function_name, error_message) 的元组
print(f"创建文件失败!错误代码: {e.winerror}, 错误信息: {e.strerror}")
return None
# --- 示例用法 ---
if __name__ == "__main__":
import os
file_to_open = "C:\\temp\\test.txt"
os.makedirs("C:\\temp", exist_ok=True)
if not os.path.exists(file_to_open):
with open(file_to_open, "w") as f:
f.write("Hello, pywin32!")
print("--- 使用 pywin32 尝试打开一个已存在的文件 ---")
create_file_with_pywin32(file_to_open)
print("\n--- 使用 pywin32 尝试打开一个不存在的文件 ---")
non_existent_file = "C:\\temp\\non_existent_pywin32.txt"
create_file_with_pywin32(non_existent_file)
总结与对比
| 特性 | ctypes (标准库) |
pywin32 (第三方库) |
|---|---|---|
| 安装 | 无需安装,Python 自带 | 需要使用 pip install pywin32 |
| 易用性 | 较低,需要手动定义所有类型和常量 | 较高,常量和类型已预定义,代码更简洁 |
| 灵活性 | 极高,可以调用任何 DLL 中的任何函数 | 高,主要覆盖了常用的 Win32 API |
| 错误处理 | 通过 get_last_error() 获取错误码 |
通过捕获 pywintypes.error 异常,信息更丰富 |
| 适用场景 | 简单调用、环境受限(不能安装包)、学习底层原理 | 快速开发、需要频繁调用 Win32 API、处理复杂 Windows 任务 |
推荐:
- 如果你只是想快速实现功能,或者这个脚本需要在很多不同的 Python 环境中运行,首选
pywin32。 - 如果你想了解 Python 是如何与 DLL 交互的,或者你在一个无法安装第三方包的受限环境中,使用
ctypes是一个很好的选择。
