Python Windows服务:调用SetTokenInformation时访问被拒绝

问题描述:

我有用Python编写的Windows服务。我需要做的是在指定的用户会话中从这个服务启动一些应用程序。该服务在会话0运行,所以我用我的算法是下一个:从当前的服务,它具有Python Windows服务:调用SetTokenInformation时访问被拒绝

  1. 获取令牌(它应该有,其实)完整的系统权限。

  2. 复制它。

  3. 将我想要的会话ID分配给重复的令牌。
  4. 使用“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,然后关闭您的防病毒程序并重试您的代码。

+0

非常感谢您为此问题投入了大量时间并试用此示例。您是否设法运行上面的代码,并且在调用SetTokenInformation之后不发生任何错误? – banana36

的解决方案是使用DuplicateTokenEx代替DuplicateToken的:

duplicated = win32security.DuplicateTokenEx(token, 
               impersonation_lvl, 
               win32security.TOKEN_ALL_ACCESS, 
               win32security.TokenPrimary) 

然后SetTokenInformation运作良好,并没有失败,拒绝访问错误。