python - 如何使用 Ctypes 和 kernel32.dll 将 Python 脚本添加到注册表
问题描述
我正在尝试将我的程序添加到注册表,这是我的代码...
def regc():
reg = windll.kernel32
print(reg)
hkey = 'HKEY_CURRENT_USER'
lsubkey = 'Software\Microsoft\Windows\CurrentVersion\Run'
reserved = 0
flag = 'REG_OPTION_BACKUP_RESTORE'
samdesired = 'KEY_ALL_ACCESS'
ipsec = None
handle = reg.RegCreateKeyExA(hkey, lsubkey, reserved, flag, samdesired, ipsec, None)
它没有给我任何错误,但它仍然没有在注册表中创建新键。我究竟做错了什么?
解决方案
要ctypes
正确使用,请定义参数.argtypes
并.restype
对其进行错误检查。许多使用的类型是错误的。 hkey
, flag
, 和samdesired
不是字符串,例如。返回值不是句柄,而是状态。返回值是一个输出参数(pkhResult
在文档中)。您必须阅读文档并仔细检查所有变量定义的头文件。
另外,在 Python 3 中字符串是 Unicode,所以使用W
Windows API 的形式来接受 Unicode 字符串。对子键使用原始字符串 ( r'...'
),因为它包含可以解释为转义码的反斜杠。
这是一个工作示例:
from ctypes import *
from ctypes import wintypes as w
# Values found from reading RegCreateKeyExW documentation,
# using Go To Definition on the types in Visual Studio,
# and printing constants in a C program, e.g. printf("%lx\n",KEY_ALL_ACCESS);
HKEY = c_void_p
PHKEY = POINTER(HKEY)
REGSAM = w.DWORD
LPSECURITY_ATTRIBUTES = c_void_p
LSTATUS = w.LONG
# Disposition values
REG_CREATED_NEW_KEY = 0x00000001
REG_OPENED_EXISTING_KEY = 0x00000002
ERROR_SUCCESS = 0
HKEY_CURRENT_USER = c_void_p(0x80000001)
REG_OPTION_NON_VOLATILE = 0
KEY_ALL_ACCESS = 0x000F003F
dll = WinDLL('kernel32')
dll.RegCreateKeyExW.argtypes = HKEY,w.LPCWSTR,w.DWORD,w.LPWSTR,w.DWORD,REGSAM,LPSECURITY_ATTRIBUTES,PHKEY,w.LPDWORD
dll.RegCreateKeyExW.restype = LSTATUS
hkey = HKEY_CURRENT_USER
lsubkey = r'Software\Microsoft\Windows\CurrentVersion\Run'
options = REG_OPTION_NON_VOLATILE
samdesired = KEY_ALL_ACCESS
# Storage for output parameters...pass by reference.
handle = HKEY()
disp = w.DWORD()
status = dll.RegCreateKeyExW(HKEY_CURRENT_USER, lsubkey, 0, None, options, samdesired, None, byref(handle), byref(disp))
if status == ERROR_SUCCESS:
print(f'{disp=} {handle=}')
输出:
disp=c_ulong(2) handle=c_void_p(3460)
处置值 2 表示键已存在 ( REG_OPENED_EXISTING_KEY
)。
您还可以安装pywin32并使用win32api.RegCreateKey
或win32api.RegCreateKeyEx
在所有工作已经为您完成的地方。
推荐阅读
- python - 有没有办法将 geotif 作为输入数据放入张量流或 python 中的 keras 中?
- python - 如何使用 Python TypeError 通过 Elasticsearch 更新或插入?
- javascript - 在javascript中找到html元素的结束标记
- vue.js - 将 json 传递给其他 vue 组件
- ios - 即使应用程序终止,也能快速显示本地通知
- ios - 如何在 swift 4.1 和 xcode 9.3 中使用 JSONDecoder 解码嵌套的 JSON 数组和对象?
- c# - 如何停止在 Visual Studio 2015 中打开的每个文件上出现编码弹出窗口
- symfony - 无法从 Symfony 供应商文件夹中的 GitHub 安装自定义文件夹
- php - 非常简单的用户认证php
- apache-spark - 根据指定位置拆分列