pywin32操作Windows API
近期尝试研究通过pywin32调用Windows api去执行一些任务,但是网上相关资料太少,故此这里做一个记录
获取Windows防火墙规则¶
直接放代码
Python
以上代码可以将系统防火墙的规则都可以获取 import win32com.client
def list_firewall_rules():
# 创建一个COM对象,用于访问Windows防火墙API
firewall = win32com.client.Dispatch("HNetCfg.FwPolicy2")
# 获取所有防火墙规则
rules = firewall.Rules
# 遍历并打印每个规则
for rule in rules:
print(f"Name: {rule.Name}")
print(f'ApplicationName:{rule.ApplicationName}')
print(f"Description: {rule.Description}")
print(f"Direction: {rule.Direction}")
print(f"Enabled: {rule.Enabled}")
print(f"Grouping: {rule.Grouping}")
print(f"Profiles: {rule.Profiles}")
print("--------------------------")
if __name__ == "__main__":
list_firewall_rules()
代码来源: phind生成
引用资料来源:python 控制Windows防火墙(FireWall)-简书
添加防火墙出站规则¶
直接放代码
Python
import win32com.client
def add_firewall_rule(name, description, application_path, action="allow"):
"""
添加一个出站规则到Windows防火墙
:param name: 规则名称
:param description: 规则描述
:param application_path: 应用程序路径
:param action: 规则动作("allow" 或 "block")
"""
# 初始化防火墙管理器
firewall_manager = win32com.client.Dispatch("HNetCfg.FwPolicy2")
# 创建新的出站规则
new_rule = win32com.client.Dispatch("HNetCfg.FWRule")
new_rule.Name = name
new_rule.Description = description
new_rule.ApplicationName = application_path
new_rule.Action = 1 if action.lower() == "allow" else 0 # 1 表示允许,0 表示阻止
new_rule.Direction = 2 # 2 表示出站规则
new_rule.Enabled = True
new_rule.Protocol = 6 # TCP
new_rule.LocalPorts = "80,443" # 举例,允许通过HTTP和HTTPS端口
# 将规则添加到防火墙
firewall_manager.Rules.Add(new_rule)
# 示例:添加一个规则
if __name__ == "__main__":
rule_name = "My Custom Outbound Rule"
rule_description = "Allow my application to access the internet."
application_path = "C:\\Path\\To\\Your\\Application.exe"
add_firewall_rule(rule_name, rule_description, application_path, "allow")
代码来源: GPT-4
获取系统中所有用户信息¶
在某些情况下需要获取当前系统标准账户和管理员账户的用户名称,同时需要过滤掉不符合条件的用户,这个时候用Windows API操作相对比较准确
直接放代码:
Python
import win32net
import win32netcon
def get_filtered_windows_users():
users_info = []
resume_handle = 0
while True:
# 使用win32net.NetUserEnum枚举用户
result, total_entries, resume_handle = win32net.NetUserEnum(
None, # None 表示本地计算机
3, # level 3 表示获取详细信息
win32netcon.FILTER_NORMAL_ACCOUNT, # 筛选标准,这里表示普通帐户
resume_handle
)
for user in result:
# 检查账户是否被禁用
account_disabled = user['flags'] & win32netcon.UF_ACCOUNTDISABLE
# 如果账户被禁用,则跳过
if account_disabled:
continue
# 用户权限级别(USER_PRIV_*)根据 win32netcon 枚举
if user['priv'] == win32netcon.USER_PRIV_USER or user['priv'] == win32netcon.USER_PRIV_ADMIN:
priv_level = "Administrator" if user['priv'] == win32netcon.USER_PRIV_ADMIN else "Standard User"
user_details = {
"Username": user['name'],
"Privilege Level": priv_level
}
users_info.append(user_details)
# 当没有更多的用户信息时,跳出循环
if not resume_handle:
break
return users_info
filtered_users = get_filtered_windows_users()
for user in filtered_users:
print(f"Username: {user['Username']}")
print(f"Privilege Level: {user['Privilege Level']}")
print()
代码来源: GPT-4
获取系统版本¶
在有些情况下需要获取某个可执行程序的版本号以做一些排序处理,而python默认提供的文件属性中并没有提供这个功能,这个时候利用Windows API操作也比较方便,直接放代码
Python
import win32api
def get_file_info(filename, info_type='FileVersion'):
"""
获取文件的版本信息
:param filename: 文件路径
:param info_type: 信息类型,比如 'FileVersion' 或 'ProductVersion'
:return: 对应的版本信息
"""
try:
# 获取文件的属性信息
info = win32api.GetFileVersionInfo(filename, '\\')
# 根据信息类型获取属性
ms = info['FileVersionMS']
ls = info['FileVersionLS']
version = f'{win32api.HIWORD(ms)}.{win32api.LOWORD(ms)}.{win32api.HIWORD(ls)}.{win32api.LOWORD(ls)}'
if info_type == 'ProductVersion':
version = f'{win32api.HIWORD(ms)}.{win32api.LOWORD(ms)}'
return version
except Exception as e:
print(f"Error occurred: {e}")
return None
# 使用方法:
file_version = get_file_info(r"python-3.11.5-amd64.exe", 'FileVersion')
product_version = get_file_info(r"python-3.11.5-amd64.exe", 'ProductVersion')
print(f"File Version: {file_version}")
print(f"Product Version: {product_version}")
代码来源: GPT-4
总结
利用Windows API执行一些特定的任务确实要方便不少,可能也有的人会觉着,像前两种方法也不一定要通Windows API来实现,cmd不就可以吗?
确实如此,但这里之所以坚持用Windows API来实现,有两方面考虑:
- (个人喜好)编写出更符合python风格的代码,不喜欢夹杂着cmd和python的代码
- (技术栈选择)在某些情况下使用Windows API会比用cmd命令更好一些。比如如果通过subprocess调用cmd执行一些任务,你会发现无法等到结果就开始执行下面的代码,会比较麻烦,但是利用Windows API去实现就没有这个问题
因此是否选择通过调用Windows API去实现一些功能,则取决于自己的项目需要