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 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 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 wakeup(minutes): os.system( 'powercfg /SETACVALUEINDEX SCHEME_CURRENT SUB_NONE CONSOLELOCK 0') minutes = int(minutes) handle = CreateWaitableTimer(None, True, 'Wake up') dt = -10000000 * minutes * 60 # Convert to seconds. SetWaitableTimer(handle, dt, 0, None, None, True) rc = WaitForSingleObject(handle, 1000 * (minutes + 1) * 60) # 11 s. os.system( 'powercfg /SETACVALUEINDEX SCHEME_CURRENT SUB_NONE CONSOLELOCK 1')
def _checkUntilClosed(processHandle, writeBack, item, localContentPath): """ Waits until the opened application is closed, writes data back, and removes the temporary file. """ startModificationTime = os.path.getmtime(localContentPath) WaitForSingleObject(processHandle, INFINITE) finalModificationTime = os.path.getmtime(localContentPath) if writeBack and startModificationTime != finalModificationTime: if item.capabilities.canStoreData: fh = open(localContentPath, "rb") item.storeData(fh) os.remove(localContentPath)
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 _tx_task(self): SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL) while self._runing: end_time = self.tx_poll_interval + time.time() with self._tx_lock: for sender in self._senders: msg = sender() if type(msg) is list: for m in msg: self._msg_send(m) elif msg is not None: self._msg_send(msg) time_left = end_time - time.time() time_left = max(0, int(time_left * 1000)) WaitForSingleObject(self._tx_event, time_left) ResetEvent(self._tx_event)
def kill(pid, sig): """Send the signal sig to the remote process. """ # open the remote process # XXX why do we need PROCESS_VM_OPERATION? flags = PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION hProcess = OpenProcess(flags, False, pid) # obtain the address of the raise method in the MSVCR71 module pfn = GetRemoteProcAddress(pid, "MSVCR71", "raise") # create a remote thread that calls raise hThread = CreateRemoteThread(hProcess, pfn, sig) # wait for thread termination WaitForSingleObject(hThread, INFINITE)
def notifyOnExit(self, processHandle, processTransport): processHandleKey = self.phandleToPhandleKey[processHandle] # If there are available threads, use one of them if len(self.availableThreads) > 0: wfmoThread = self.availableThreads[0] self.threadToNumProcessHandles[wfmoThread] += 1 self.phandleKeyToThreadHandle[processHandleKey] = wfmoThread # Update used/available thread lists if self.threadToNumProcessHandles[wfmoThread] == 63: self.usedThreads.append(wfmoThread) self.availableThreads.remove(wfmoThread) # Make sure the message window has been created so # we can send messages to the thread. if self.threadToMsgWindowCreated[wfmoThread] is False: val = WaitForSingleObject( self.threadToMsgWindowCreationEvent[wfmoThread], INFINITE) if val != WAIT_OBJECT_0: raise RuntimeError( "WaitForSingleObject returned %d. It should only return %d" % (val, WAIT_OBJECT_0)) # Notify the thread that it should wait on the process handle. if win32api.PostMessage( self.threadToMsgWindow[wfmoThread], WM_NEW_PHANDLE, # message processHandleKey, # wParam 0 # lParam ) == 0: raise Exception("Failed to post thread message!") else: # Create a new thread and wait on the proc handle wfmoThread = threading.Thread( target=self.doWaitForProcessExit, args=(processHandleKey, ), name= "iocpreactor.process_waiter.ProcessWaiter.waitForProcessExit pid=%d" % self.realPid) # Create a window creation event that will be triggered from the thread self.threadToMsgWindowCreationEvent[wfmoThread] = CreateEvent( None, 0, 0, None) self.threadToMsgWindowCreated[wfmoThread] = False self.threadToNumProcessHandles[wfmoThread] = 1 self.availableThreads.append(wfmoThread) self.phandleKeyToThreadHandle[processHandleKey] = wfmoThread wfmoThread.start()
def acquire(self, timeout=TIMEOUT_INFINITE): """ gets mutex due to legacy reasons there's still the initial acquire mode, which is intended for ensuring, that a certain executable is called only once. (will_own=1) """ if self.will_own: self.handle = CreateMutex(None, self.will_own, self.name) err = GetLastError() if err == ERROR_ALREADY_EXISTS: return False else: return self rslt = WaitForSingleObject(self.handle, timeout) if rslt == MTX_WAIT_OBJECT_O: return self elif rslt == MTX_WAIT_TIMEOUT: return False raise IPCMutexError("got got return code %08x" % rslt)
def processEnded(self, processHandle, processHandleKey): wfmoThread = self.phandleKeyToThreadHandle[processHandleKey] processTransport = self.phandleToTransport[processHandle] self.threadToNumEnded[wfmoThread] += 1 # Decrement proc handle count for thread self.threadToNumProcessHandles[wfmoThread] -= 1 # If we go from 63 to 62 phandles for the thread, mark it available. if self.threadToNumProcessHandles[wfmoThread] == 62: self.availableThreads.append(wfmoThread) self.usedThreads.remove(wfmoThread) # If we go to 0 phandles, end the thread elif self.threadToNumProcessHandles[wfmoThread] == 0: # Mark thread as unavailable self.availableThreads.remove(wfmoThread) # Notify the thread that it should exit. if not self.threadToMsgWindowCreated[wfmoThread]: val = WaitForSingleObject( self.threadToMsgWindowCreationEvent[wfmoThread], INFINITE) if val != WAIT_OBJECT_0: raise RuntimeError( "WaitForSingleObject returned %d. It should only return %d" % (val, WAIT_OBJECT_0)) # Notify the thread that it should wait on the process handle. win32api.PostMessage( self.threadToMsgWindow[wfmoThread], # thread id WM_CLOSE_THREAD, # message 0, # wParam 0 # lParam ) # Cleanup thread resources del self.threadToNumProcessHandles[wfmoThread] del self.threadToMsgWindowCreated[wfmoThread] #del self.wfmoThread # Cleanup process handle resources del self.needWaiting[processHandleKey] del self.phandleToTransport[processHandle] # Call the transport's processEnded method processTransport.processEnded()
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 _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
def _interrupt(self): rc = WaitForSingleObject(self.hWaitStop, 0) if rc == WAIT_OBJECT_0: raise SystemExit()
def waitEvents(self): return (WaitForSingleObject(self.event, 30000) == WAIT_OBJECT_0)
def measure(arg, commandline, delay, maxtime, outFile=None, errFile=None, inFile=None, logger=None, affinitymask=None): m = Record(arg) # For % CPU usage cpu0 = taskManagerCpuTimes() ### Use a JobObject so we capture data for child processes as well hJob = CreateJobObject(None, 'proctree') # For elapsed time try QueryPerformanceCounter otherwise use GetTickCount freq = LARGE_INTEGER() isCounter = windll.kernel32.QueryPerformanceFrequency(byref(freq)) if isCounter: t0 = LARGE_INTEGER() t = LARGE_INTEGER() windll.kernel32.QueryPerformanceCounter(byref(t0)) else: # the number of milliseconds since windows started t0 = GetTickCount() try: # spawn the program in a separate process p = Popen(commandline, stdout=outFile, stderr=errFile, stdin=inFile) hProcess = int(p._handle) AssignProcessToJobObject(hJob, hProcess) # wait for program exit status - time out in milliseconds waitexit = WaitForSingleObject(hProcess, maxtime * 1000) # For elapsed time try QueryPerformanceCounter otherwise use GetTickCount if isCounter: windll.kernel32.QueryPerformanceCounter(byref(t)) m.elapsed = (t.value - t0.value) / float(freq.value) else: # the number of milliseconds since windows started t = GetTickCount() m.elapsed = (t - t0) / 1000.0 if waitexit != 0: # terminate any child processes as well TerminateJobObject(hJob, -1) m.setTimedout() elif p.poll() == 0: m.setOkay() ### Use a JobObject so we capture data for child processes as well times = QueryInformationJobObject( hJob, JobObjectBasicAccountingInformation) #ten million - the number of 100-nanosecond units in one second totalusr = times['TotalUserTime'] / nanosecs100 totalsys = times['TotalKernelTime'] / nanosecs100 m.userSysTime = totalusr + totalsys ### "VM Size" seems the more appropriate measure ### # corresponds to Peak Mem Usage in Task Manager # mem = GetProcessMemoryInfo(hProcess) # m.maxMem = mem['PeakWorkingSetSize'] / 1024 # corresponds to VM Size in Task Manager mem = QueryInformationJobObject(hJob, JobObjectExtendedLimitInformation) m.maxMem = mem['PeakJobMemoryUsed'] / 1024 m.cpuLoad = taskManagerCpuLoad(cpu0, taskManagerCpuTimes(), totalusr) elif p.poll() == 2: m.setMissing() else: m.setError() except (OSError, ValueError), (e, err): if logger: logger.error('%s %s', e, err) m.setError()
def wait(self, timeout): """Wait for editor to exit or until timeout""" WaitForSingleObject(self.handle, int(timeout * 1000.0))
def _spawn(self, command, args=None): """Start the child process. If args is empty, command will be parsed according to the rules of the MS C runtime, and args will be set to the parsed args.""" if args: args = args[:] # copy args.insert(0, command) else: args = split_command_line(command) command = args[0] self.command = command self.args = args command = which(self.command) if command is None: raise ExceptionPexpect('Command not found: %s' % self.command) args = join_command_line(self.args) # Create the pipes sids = [_get_current_sid()] if self.username and self.password: sids.append(_lookup_sid(self.domain, self.username)) cmd_pipe, cmd_name = _create_named_pipe(self.pipe_template, sids) stdin_pipe, stdin_name = _create_named_pipe(self.pipe_template, sids) stdout_pipe, stdout_name = _create_named_pipe(self.pipe_template, sids) stderr_pipe, stderr_name = _create_named_pipe(self.pipe_template, sids) startupinfo = STARTUPINFO() startupinfo.dwFlags |= STARTF_USESHOWWINDOW startupinfo.wShowWindow = SW_HIDE python = os.path.join(sys.exec_prefix, 'python.exe') pycmd = 'import winpexpect; winpexpect._stub(r"%s", r"%s", r"%s", r"%s")' \ % (cmd_name, stdin_name, stdout_name, stderr_name) pyargs = join_command_line([python, '-c', pycmd]) # Create a new token or run as the current process. if self.username and self.password: token = LogonUser(self.username, self.domain, self.password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT) res = CreateProcessAsUser(token, python, pyargs, None, None, False, CREATE_NEW_CONSOLE, self.env, self.cwd, startupinfo) else: token = None res = CreateProcess(python, pyargs, None, None, False, CREATE_NEW_CONSOLE, self.env, self.cwd, startupinfo) child_handle = res[0] res[1].Close() # don't need thread handle ConnectNamedPipe(cmd_pipe) ConnectNamedPipe(stdin_pipe) ConnectNamedPipe(stdout_pipe) ConnectNamedPipe(stderr_pipe) # Tell the stub what to do and wait for it to exit WriteFile(cmd_pipe, 'command=%s\n' % command) WriteFile(cmd_pipe, 'args=%s\n' % args) if token: parent_sid = ConvertSidToStringSid(_get_current_sid()) WriteFile(cmd_pipe, 'parent_sid=%s\n' % str(parent_sid)) WriteFile(cmd_pipe, '\n') header = _read_header(cmd_pipe) output = _parse_header(header) if output['status'] != 'ok': m = 'Child did not start up correctly. ' m += output.get('message', '') raise ExceptionPexpect(m) self.pid = int(output['pid']) self.child_handle = OpenProcess(PROCESS_ALL_ACCESS, False, self.pid) WaitForSingleObject(child_handle, INFINITE) # Start up the I/O threads self.child_fd = open_osfhandle(stdin_pipe.Detach(), 0) # for pexpect self.stdout_handle = stdout_pipe self.stdout_reader = Thread(target=self._child_reader, args=(self.stdout_handle,)) self.stdout_reader.start() self.stderr_handle = stderr_pipe self.stderr_reader = Thread(target=self._child_reader, args=(self.stderr_handle,)) self.stderr_reader.start() self.terminated = False self.closed = False