我需要使用Python(版本3)上的Windows(10)上的服务。在开始和停止之前,我需要获得服务句柄。首先,我获得SCManager句柄(成功),之后我尝试通过OpenService
获取服务句柄(例如,它是“Dhcp”服务)。这是我的代码:
from ctypes import *
from ctypes.wintypes import *
OpenSCManager = windll.advapi32.OpenSCManagerA
OpenService = windll.advapi32.OpenServiceA
GetLastError = windll.kernel32.GetLastError
SC_MANAGER_ALL_ACCESS = DWORD(0xF003F)
SERVICE_ALL_ACCESS = DWORD(0xF01FF)
name = "Dhcp"
sc_manager_h = OpenSCManager(None, None, SC_MANAGER_ALL_ACCESS)
if sc_manager_h == 0:
raise Exception(GetLastError())
else:
print(sc_manager_h) # <-- OK, no exception, printed some number
service_h = OpenService(sc_manager_h, name.encode("ascii"), SERVICE_ALL_ACCESS)
if service_h == 0:
raise Exception(GetLastError()) # <-- here raised Exception, GetLastError is 6 (ERROR_INVALID_HANDLE)
else:
print(service_h)
print(GetLastError())
用户(我在管理员下运行),运行代码,没事(我试图在没有权限的用户下运行,OpenSCManager
引发了正确的错误)。我也确定这不是名称或服务助手常量的问题,还有另外GetLastError
代码。存在具有这种名称的服务(在我的情况下为“Dhcp”)。 似乎就像某种程度上我以错误的方式将SCManager句柄传递给OpenService
,但我不知道怎么回事。
OpenService
上的文档:https://msdn.microsoft.com/en-us/library/windows/desktop/ms684330(v=vs.85).aspx
更新1
正如@conio建议的那样,我尝试了相同的C代码,并且效果很好。我也尝试在下一台机器\解释器上运行上面的代码:
service_h
不是0,
GetLastError为0; service_h
不为0,GetLastError为0; service_h
不为0,GetLastError为6,service_h
可用于其他服务功能,如{{ 1}} StartService
不为0,GetLastError为0; service_h
为0,GetLastError为6,引发异常。总结这些测试:
service_h
返回0并且上面的代码中出现错误,有时它返回正确的句柄,可以在其他服务函数中使用像OpenService
,这个功能很好(至少我试图启动服务,它开始)。