2017-06-20 155 views
0

我有用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) 

回答

1

在窗口10,以管理員身份運行,與ActivePython的2.7 32位最新+ pywin32最新的,你的代碼完美的作品。

我建議嘗試使用ActivePython並更新您的pywin32,然後關閉您的防病毒程序並重試您的代碼。

+0

非常感謝您爲此問題投入了大量時間並試用此示例。您是否設法運行上面的代碼,並且在調用SetTokenInformation之後不發生任何錯誤? – banana36

0

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

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

然後SetTokenInformation運作良好,並沒有失敗,拒絕訪問錯誤。