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)

原创内容,如需转载,请注明出处;

本文地址: https://www.perfcode.com/p/811.html

分类: 计算机技术
推荐阅读:
Golang生成一个整数范围内的随机整数 在Golang中,可以通过math/rand包的Intn(n)函数生成一个0~n之间的随机整数,碰到100~200、-10~10这样的整数段却无能为力了;
禁用Visual Studio自动下载更新 近日,作者使用Visual Studio发现,Visual Studio会自己在后台下载更新内容,然后提醒你是否安装;因为Visual Studio的更新包体积庞大,不仅占用网络资源也会消耗磁盘性能,所以我决定禁用它;
Python dict()函数 在Python中,dict()函数用于创建一个字典对象。它可以接受不同类型的参数,并根据参数的不同生成字典对象。具体来说,dict()函数有以下三种使用方式:
Socket error Event: 32 Error: 10053.解决方法 在使用Xshell连接服务器时,偶尔会发生这类错误:Socket error Event: 32 Error: 10053.Connection closing...Socket close.
什么是可打印字符? 可打印字符是指在文本中可以显示和输出的字符,包括字母、数字、标点符号和一些特殊符号。根据ASCII编码标准,ASCII码范围内的可打印字符的值为 32(空格)到 126(波浪号)。
使用Session实例让requests保持会话 Session对象能让你跨请求保持某些参数;最长常见的是,当你使用requests尝试登录并且验证成功,服务端会返回一些Cookie,这些Cookie可以使你的下次请求不需要验证,而Session对象能保持这些Cookie,而不用你每次提交请求时构建一个新的Cookie。