Python调用Windows API的一个简单例子
Python调用WINDOWS API的方法有多种,本文将使用Python 调用WINDOWS API来获取系统的版本信息。
先来介绍一下获取版本信息的API函数GetVersionExA,该函数在kernell32.dll动态库中。其原型如下:
BOOL GetVersionEx(POSVERSIONINFO pVersionInformation);
POSVERSIONINFO结构如下:
typedef struct {
DWORD dwOSVersionInfoSize; //在使用GetVersionEx之前要将此初始化为结构的大小
DWORD dwMajorVersion; //系统主版本号
DWORD dwMinorVersion; //系统次版本号
DWORD dwBuildNumber; //系统构建号
DWORD dwPlatformId; //系统支持的平台
TCHAR szCSDVersion[128]; //系统补丁包的名称
WORD wServicePackMajor; //系统补丁包的主版本
WORD wServicePackMinor; //系统补丁包的次版本
WORD wSuiteMask; //标识系统上的程序组
BYTE wProductType; //标识系统类型
BYTE wReserved; //保留,未使用
} OSVERSIONINFOEX, *POSVERSIONINFOEX
将 POSVERSIONINFO 结构用python表现出来:
import ctypes
class POSVERSIONINFO(ctypes.Structure):
_fields_ = [
("dwOSVersionInfoSize",ctypes.c_long),
("dwMajorVersion",ctypes.c_long),
("dwMinorVersion",ctypes.c_long),
("dwBuildNumber",ctypes.c_long),
("dwPlatformId",ctypes.c_long),
("szCSDVersion",ctypes.c_char*128),
("wServicePackMajor",ctypes.c_ushort),
("wServicePackMinor",ctypes.c_ushort),
("wSuiteMask",ctypes.c_ushort),
("wProductType",ctypes.c_byte),
("wReserved",ctypes.c_byte)
]
对应的数据类型不能错,否则将调用失败。
首先加载kernel32.dll文件,加载dll文件的方法有多种,具体怎么加载取决于DLL编译时的调用约定,此文不对这面进行论述。
kernell32.dll是系统核心文件,导入ctypes时会自动加载,可直接使用。
kernel32 = ctypes.windll.kernel32
返回的是DLL对象,现在可直接用调用方法的方式调用API函数,不过在这之前,需要初始化一下POSVERSIONINFO结构体。
os = POSVERSIONINFO()
再计算结构体大小,并传入dwOSVersionInfoSize:
os.dwOSVersionInfoSize = ctypes.sizeof(os)
结构体初始化完毕,再获得其指针:
os_p = ctypes.byref(os)
开始调用API,GetVersionEx调用成功则返回1,失败则返回0:
if kernel32.GetVersionExA(os_p)==0:
print("Null")
exit()
失败则程序退出,成功则可通过下面的方法获得版本信息:
print(os.dwOSVersionInfoSize)
print(os.dwMajorVersion)
print(os.dwMinorVersion)
print(os.dwBuildNumber)
print(os.dwPlatformId)
print(os.szCSDVersion.decode())
print(os.wServicePackMajor)
print(os.wServicePackMinor)
print(os.wSuiteMask)
print(os.wProductType)
完整代码
import ctypes
class POSVERSIONINFO(ctypes.Structure):
_fields_ = [
("dwOSVersionInfoSize",ctypes.c_long),
("dwMajorVersion",ctypes.c_long),
("dwMinorVersion",ctypes.c_long),
("dwBuildNumber",ctypes.c_long),
("dwPlatformId",ctypes.c_long),
("szCSDVersion",ctypes.c_char*128),
("wServicePackMajor",ctypes.c_ushort),
("wServicePackMinor",ctypes.c_ushort),
("wSuiteMask",ctypes.c_ushort),
("wProductType",ctypes.c_byte),
("wReserved",ctypes.c_byte)
]
kernel32 = ctypes.windll.kernel32
os = POSVERSIONINFO()
os.dwOSVersionInfoSize = ctypes.sizeof(os)
os_p = ctypes.byref(os)
if kernel32.GetVersionExA(os_p)==0:
print("Null")
exit()
print(os.dwOSVersionInfoSize)
print(os.dwMajorVersion)
print(os.dwMinorVersion)
print(os.dwBuildNumber)
print(os.dwPlatformId)
print(os.szCSDVersion.decode())
print(os.wServicePackMajor)
print(os.wServicePackMinor)
print(os.wSuiteMask)
print(os.wProductType)