def wait(self): """Wait for child process to terminate. Returns returncode attribute.""" if self.returncode is None: obj = WaitForSingleObject(self._handle, INFINITE) self.returncode = GetExitCodeProcess(self._handle) return self.returncode
def _internal_poll(self, _deadstate=None): """Check if child process has terminated. Returns returncode attribute.""" if self.returncode is None: if WaitForSingleObject(self._handle, 0) == WAIT_OBJECT_0: self.returncode = GetExitCodeProcess(self._handle) return self.returncode
def poll(self): """Check if child process has terminated. Returns returncode attribute.""" if self.returncode == None: if WaitForSingleObject(self._handle, 0) == WAIT_OBJECT_0: self.returncode = GetExitCodeProcess(self._handle) _active.remove(self) return self.returncode
def isalive(self): """Return True if the child is alive, False otherwise.""" if self.exitstatus is not None: return False ret = WaitForSingleObject(self.child_handle, 0) if ret == WAIT_OBJECT_0: self.exitstatus = GetExitCodeProcess(self.child_handle) return False return True
def wait(self, timeout=None): """Wait until the child exits. If timeout is not specified this blocks indefinately. Otherwise, timeout specifies the number of seconds to wait.""" if self.exitstatus is not None: return if timeout is None: timeout = INFINITE else: timeout = 1000 * timeout ret = WaitForSingleObject(self.child_handle, timeout) if ret == WAIT_TIMEOUT: raise TIMEOUT('Timeout exceeded in wait().') self.exitstatus = GetExitCodeProcess(self.child_handle) return self.exitstatus
def run_as_admin(exe, params, as_admin=True): import win32com.shell.shell as shell import win32con from win32process import GetExitCodeProcess import win32event import pywintypes try: # Try to launch process as administrator in case exception was # due to insufficient privileges. # To make process call block, set `fMask` parameter to return # handle to process that can be monitored to wait for the # process to exit. See the [SHELLEXECUTEINFO structure # documentation][1] for details. # # [1]: https://msdn.microsoft.com/en-us/library/windows/desktop/bb759784%28v=vs.85%29.aspx SEE_MASK_NOASYNC = 0x00000100 SEE_MASK_NOCLOSEPROCESS = 0x00000040 WAIT_FOREVER = -1 launch_kwargs = dict(lpFile=exe, lpParameters=params, nShow=win32con.SW_SHOW, fMask=(SEE_MASK_NOASYNC | SEE_MASK_NOCLOSEPROCESS)) if as_admin: launch_kwargs['lpVerb'] = 'runas' process_info = shell.ShellExecuteEx(**launch_kwargs) win32event.WaitForSingleObject(process_info['hProcess'], WAIT_FOREVER) return_code = GetExitCodeProcess(process_info['hProcess']) if return_code == 0: return '' else: raise RuntimeError('Process returned error code: %s' % return_code) except pywintypes.error as e: if e.winerror == 1223: # Error 1223 is elevation cancelled. raise CancelAction(e.strerror) else: raise
def run_as_admin(wait_exit: bool = True) -> Optional[int]: # noinspection PyUnresolvedReferences from win32com.shell.shell import ShellExecuteEx from win32event import WaitForSingleObject, INFINITE from win32process import GetExitCodeProcess # import win32con # noinspection PyUnresolvedReferences from win32com.shell import shellcon import win32api cmd = '"%s"' % sys.executable params = ' '.join(['"%s"' % x for x in sys.argv]) proc = ShellExecuteEx( lpFile=cmd, lpParameters=params, lpVerb='runas', # nShow=win32con.SW_SHOWNORMAL, fMask=shellcon.SEE_MASK_NOCLOSEPROCESS) if wait_exit: handle = proc['hProcess'] WaitForSingleObject(handle, INFINITE) rc = GetExitCodeProcess(handle) win32api.CloseHandle(handle) return rc
def isAlive(self): """Returns true if the editor process is still alive""" return GetExitCodeProcess(self.handle) == 259
def _call_command(command, logoutput=False, cwd=None, env=None, wait_for_finish=True, timeout=None, user=None): # TODO implement timeout, wait_for_finish Logger.info("Executing %s" % (command)) if user: domain, username = UserHelper.parse_user_name(user, ".") proc_token = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES) old_states = [] privileges = [ SE_ASSIGNPRIMARYTOKEN_NAME, SE_INCREASE_QUOTA_NAME, ] for priv in privileges: old_states.append(QueryPrivilegeState(proc_token, priv)) AdjustPrivilege(proc_token, priv) QueryPrivilegeState(proc_token, priv) user_token = LogonUser(username, domain, Script.get_password(user), win32con.LOGON32_LOGON_SERVICE, win32con.LOGON32_PROVIDER_DEFAULT) env_token = DuplicateTokenEx(user_token, SecurityIdentification, TOKEN_QUERY, TokenPrimary) # getting updated environment for impersonated user and merge it with custom env current_env = CreateEnvironmentBlock(env_token, False) current_env = _merge_env(current_env, env) si = STARTUPINFO() out_handle, err_handle, out_file, err_file = _create_tmp_files( current_env) ok, si.hStdInput = _safe_duplicate_handle( GetStdHandle(STD_INPUT_HANDLE)) if not ok: raise Exception("Unable to create StdInput for child process") ok, si.hStdOutput = _safe_duplicate_handle(out_handle) if not ok: raise Exception("Unable to create StdOut for child process") ok, si.hStdError = _safe_duplicate_handle(err_handle) if not ok: raise Exception("Unable to create StdErr for child process") Logger.debug("Redirecting stdout to '{0}', stderr to '{1}'".format( out_file.name, err_file.name)) si.dwFlags = win32con.STARTF_USESTDHANDLES si.lpDesktop = "" try: info = CreateProcessAsUser(user_token, None, command, None, None, 1, win32con.CREATE_NO_WINDOW, current_env, cwd, si) hProcess, hThread, dwProcessId, dwThreadId = info hThread.Close() try: WaitForSingleObject(hProcess, INFINITE) except KeyboardInterrupt: pass out, err = _get_files_output(out_file, err_file) code = GetExitCodeProcess(hProcess) finally: for priv in privileges: old_state = old_states.pop(0) AdjustPrivilege(proc_token, priv, old_state) else: # getting updated environment for current process and merge it with custom env cur_token = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY) current_env = CreateEnvironmentBlock(cur_token, False) current_env = _merge_env(current_env, env) proc = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=cwd, env=current_env, shell=False) out, err = proc.communicate() code = proc.returncode if logoutput and out: Logger.info(out) if logoutput and err: Logger.info(err) return code, out, err