python win32service - 获取服务的触发启动信息
python win32service - Getting triggered startup information for service
win32 API QueryServiceConfig2 function supports the SERVICE_CONFIG_TRIGGER_INFO structure to get event(s) that trigger the service startup. However, python's win32service.QueryServiceConfig2() 没有列出这样的值作为参数选项。是否可以使用 win32service 模块获取该信息?
不幸的是,没有。这是 Python 3.5 和 PyWin32 v221:
下的简单代码片段 运行
#!/usr/bin/env python3
import win32service
if __name__ == "__main__":
for name in dir(win32service):
if name.startswith("SERVICE_CONFIG_"):
print(name, getattr(win32service, name))
输出:
(py35x64_test) e:\Work\Dev\Whosebug\q046916726>"c:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" a.py
SERVICE_CONFIG_DELAYED_AUTO_START_INFO 3
SERVICE_CONFIG_DESCRIPTION 1
SERVICE_CONFIG_FAILURE_ACTIONS 2
SERVICE_CONFIG_FAILURE_ACTIONS_FLAG 4
SERVICE_CONFIG_PRESHUTDOWN_INFO 7
SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO 6
SERVICE_CONFIG_SERVICE_SID_INFO 5
我还检查了 win32con(这是另一个 PyWin32 模块,只包含常量定义),但也没有运气。
然后,我查看了 ${PYWIN32_SRC_DIR}/pywin32-221/win32/src/win32service.i,并注意到 ChangeServiceConfig2(还有 QueryServiceConfig2),InfoLevel 参数专门针对上述常量进行检查,因此直接传递其值 (8) 会引发异常 (NotImplementedError)。
在进一步讨论之前,让我们花一点时间了解调用这样的 Python 包装器(如 win32service.QueryServiceConfig2
)时会发生什么:
- 参数(Python 样式 - 如果有)转换为 C 样式
- C 函数使用上述转换后的参数调用
- 函数结果(或输出参数)——如果有的话——被转换回 Python
对于[MS.Docs]: ChangeServiceConfig2W function,数据通过参数来回传输运行(取决于dwInfoLevel值,lpInfo 可以有多种含义):
- 让我们看一下支持的值:例如SERVICE_CONFIG_PRESHUTDOWN_INFO:
- lpInfo 是指向 [MS.Docs]: SERVICE_PRESHUTDOWN_INFO structure 的指针,它只有一个 dwPreshutdownTimeout 成员(这是一个简单的 双字)
另一方面,SERVICE_CONFIG_TRIGGER_INFO:
- lpInfo 是指向 [MS.Docs]: SERVICE_TRIGGER_INFO structure 的指针
- pTriggers 成员是指向 [MS.Docs]: SERVICE_TRIGGER structure 的指针
- pDataItems 成员是指向 [MS.Docs]: SERVICE_TRIGGER_SPECIFIC_DATA_ITEM structure
的指针
这更复杂(请注意,所有涉及的结构还有其他成员,我只列出了增加嵌套级别的那些)。
添加对所有这些参数的支持并不是一项微不足道的任务,因此它们没有被处理(至少目前是这样)。
还有更多这样的例子,我想这是一个优先事项,因为没有多少人要求该功能,结合 MS 的(不幸的?)设计决策拥有具有如此复杂行为的功能。
作为替代方案(一个相当复杂的方案),您可以使用 [Python 3.Docs]: ctypes - A foreign function library for Python,但您必须定义我上面在 Python[ 中列出的所有结构=101=](扩展ctypes.Structure
)。
- 附带说明一下,我曾经遇到过这样的情况:我不得不调用 [MS.Docs]: LsaLogonUser function(!!! 14 个奇怪的参数!!!)。显然,它不是由 PyWin32 导出的,所以我通过 ctypes 调用它,但我不得不写:
- ~170 行定义结构的代码(只有我的场景需要的那些)
- ~50行填充它们并调用函数
win32 API QueryServiceConfig2 function supports the SERVICE_CONFIG_TRIGGER_INFO structure to get event(s) that trigger the service startup. However, python's win32service.QueryServiceConfig2() 没有列出这样的值作为参数选项。是否可以使用 win32service 模块获取该信息?
不幸的是,没有。这是 Python 3.5 和 PyWin32 v221:
下的简单代码片段 运行#!/usr/bin/env python3
import win32service
if __name__ == "__main__":
for name in dir(win32service):
if name.startswith("SERVICE_CONFIG_"):
print(name, getattr(win32service, name))
输出:
(py35x64_test) e:\Work\Dev\Whosebug\q046916726>"c:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" a.py SERVICE_CONFIG_DELAYED_AUTO_START_INFO 3 SERVICE_CONFIG_DESCRIPTION 1 SERVICE_CONFIG_FAILURE_ACTIONS 2 SERVICE_CONFIG_FAILURE_ACTIONS_FLAG 4 SERVICE_CONFIG_PRESHUTDOWN_INFO 7 SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO 6 SERVICE_CONFIG_SERVICE_SID_INFO 5
我还检查了 win32con(这是另一个 PyWin32 模块,只包含常量定义),但也没有运气。
然后,我查看了 ${PYWIN32_SRC_DIR}/pywin32-221/win32/src/win32service.i,并注意到 ChangeServiceConfig2(还有 QueryServiceConfig2),InfoLevel 参数专门针对上述常量进行检查,因此直接传递其值 (8) 会引发异常 (NotImplementedError)。
在进一步讨论之前,让我们花一点时间了解调用这样的 Python 包装器(如 win32service.QueryServiceConfig2
)时会发生什么:
- 参数(Python 样式 - 如果有)转换为 C 样式
- C 函数使用上述转换后的参数调用
- 函数结果(或输出参数)——如果有的话——被转换回 Python
对于[MS.Docs]: ChangeServiceConfig2W function,数据通过参数来回传输运行(取决于dwInfoLevel值,lpInfo 可以有多种含义):
- 让我们看一下支持的值:例如SERVICE_CONFIG_PRESHUTDOWN_INFO:
- lpInfo 是指向 [MS.Docs]: SERVICE_PRESHUTDOWN_INFO structure 的指针,它只有一个 dwPreshutdownTimeout 成员(这是一个简单的 双字)
另一方面,SERVICE_CONFIG_TRIGGER_INFO:
- lpInfo 是指向 [MS.Docs]: SERVICE_TRIGGER_INFO structure 的指针
- pTriggers 成员是指向 [MS.Docs]: SERVICE_TRIGGER structure 的指针
- pDataItems 成员是指向 [MS.Docs]: SERVICE_TRIGGER_SPECIFIC_DATA_ITEM structure 的指针
- pTriggers 成员是指向 [MS.Docs]: SERVICE_TRIGGER structure 的指针
这更复杂(请注意,所有涉及的结构还有其他成员,我只列出了增加嵌套级别的那些)。
- lpInfo 是指向 [MS.Docs]: SERVICE_TRIGGER_INFO structure 的指针
添加对所有这些参数的支持并不是一项微不足道的任务,因此它们没有被处理(至少目前是这样)。
还有更多这样的例子,我想这是一个优先事项,因为没有多少人要求该功能,结合 MS 的(不幸的?)设计决策拥有具有如此复杂行为的功能。
作为替代方案(一个相当复杂的方案),您可以使用 [Python 3.Docs]: ctypes - A foreign function library for Python,但您必须定义我上面在 Python[ 中列出的所有结构=101=](扩展ctypes.Structure
)。
- 附带说明一下,我曾经遇到过这样的情况:我不得不调用 [MS.Docs]: LsaLogonUser function(!!! 14 个奇怪的参数!!!)。显然,它不是由 PyWin32 导出的,所以我通过 ctypes 调用它,但我不得不写:
- ~170 行定义结构的代码(只有我的场景需要的那些)
- ~50行填充它们并调用函数