Python Windows服务:调用SetTokenInformation时访问被拒绝
问题描述:
我有用Python编写的Windows服务。我需要做的是在指定的用户会话中从这个服务启动一些应用程序。该服务在会话0运行,所以我用我的算法是下一个:从当前的服务,它具有Python Windows服务:调用SetTokenInformation时访问被拒绝
获取令牌(它应该有,其实)完整的系统权限。
复制它。
- 将我想要的会话ID分配给重复的令牌。
- 使用“CreateProcessAsUser”函数使用重复标记运行应用程序。
我有写在C++ windows服务上的相同的东西,它完美的工作。至于Python,我在尝试调用“SetTokenInformation”函数时发现“拒绝访问”。可能有人有一个想法,为什么会发生这种情况,或者可能可以通过Windows服务中的ID共享另一种在某个用户会话中启动进程的方式?
下面是一些代码:
class AppServerSvc (win32serviceutil.ServiceFramework):
_svc_name_ = "TestService"
_svc_display_name_ = "Test Service"
def __init__(self,args):
win32serviceutil.ServiceFramework.__init__(self,args)
self.hWaitStop = win32event.CreateEvent(None,0,0,None)
def SvcStop(self):
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.hWaitStop)
def SvcDoRun(self):
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STARTED,
(self._svc_name_,''))
self.main()
def get_next_msg(self):
address = ('localhost', 6000)
listener = Listener(address, authkey='secret password')
conn = listener.accept()
msg = conn.recv()
listener.close()
return msg
def process_msg(self):
token = win32security.OpenProcessToken(win32process.GetCurrentProcess(),
win32security.TOKEN_ALL_ACCESS)
duplicated = win32security.DuplicateToken(token, 2)
curr_proc_id = win32process.GetCurrentProcessId()
curr_session_id = win32ts.ProcessIdToSessionId(curr_proc_id)
# access denied! error code: 5
win32security.SetTokenInformation(duplicated, win32security.TokenSessionId, curr_session_id)
def main(self):
while True:
msg = self.get_next_msg()
self.process_msg()
if __name__ == '__main__':
win32serviceutil.HandleCommandLine(AppServerSvc)
答
在窗口10,以管理员身份运行,与ActivePython的2.7 32位最新+ pywin32最新的,你的代码完美的作品。
我建议尝试使用ActivePython并更新您的pywin32,然后关闭您的防病毒程序并重试您的代码。
答
的解决方案是使用DuplicateTokenEx代替DuplicateToken的:
duplicated = win32security.DuplicateTokenEx(token,
impersonation_lvl,
win32security.TOKEN_ALL_ACCESS,
win32security.TokenPrimary)
然后SetTokenInformation运作良好,并没有失败,拒绝访问错误。
非常感谢您为此问题投入了大量时间并试用此示例。您是否设法运行上面的代码,并且在调用SetTokenInformation之后不发生任何错误? – banana36