Esempio n. 1
0
 def is_in_job(self):
     try:
         if win32job.IsProcessInJob(self.get_ph(), 0):
             return 1
     except:
         pass
     return 0
Esempio n. 2
0
    def _add_to_job_object(self):
        global _global_process_job_handle
        if _global_process_job_handle is not None:
            #This means that we are creating another process family - we'll all be in the same job
            return

        already_in_job = win32job.IsProcessInJob(win32api.GetCurrentProcess(), None)

        #Create a new job and put us in it before we create any children
        logger.debug("Creating job object and adding parent process to it")
        security_attrs = win32security.SECURITY_ATTRIBUTES()
        security_attrs.bInheritHandle = 0
        _global_process_job_handle = win32job.CreateJobObject(security_attrs, self.get_job_object_name())
        extended_info = win32job.QueryInformationJobObject(_global_process_job_handle, win32job.JobObjectExtendedLimitInformation)
        extended_info['BasicLimitInformation']['LimitFlags'] = win32job.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE
        win32job.SetInformationJobObject(_global_process_job_handle, win32job.JobObjectExtendedLimitInformation, extended_info)
        try:
            win32job.AssignProcessToJobObject(_global_process_job_handle, win32api.GetCurrentProcess())
        except Exception as e:
            winv = sys.getwindowsversion()
            logger.error("Error raised during assignment of the current process to a new job object. " +\
                         "The process %s already in a job. " +\
                         "The windows version is %d.%d.\nError: %s",
                            "is" if already_in_job else "is not",
                            winv.major,
                            winv.minor,
                            _exception_str())

            if already_in_job and not (winv.major >= 6 and winv.minor >= 2):
                raise JobObjectAssignError("On Windows versions older than Windows 8 / Windows Server 2012, ProcessFamily relies on the parent process NOT being in a job already", e, already_in_job)

            raise JobObjectAssignError("Error raised during assignment of the current process to a new job object.", e, already_in_job)


        logger.debug("Added to job object")
Esempio n. 3
0
    def get_response_object(self):
        if self.path.startswith('/injob'):
            return json.dumps(win32job.IsProcessInJob(
                win32api.GetCurrentProcess(), None),
                              indent=3)
        if self.path.startswith('/job'):
            extended_info = win32job.QueryInformationJobObject(
                None, win32job.JobObjectExtendedLimitInformation)

            return json.dumps(extended_info, indent=3)
        if self.path.startswith('/close_file_and_delete_it'):
            try:
                if self.funkyserver._open_file_handle is not None:
                    f = os.path.join(os.path.dirname(__file__), 'tmp',
                                     'testfile.txt')
                    logging.info("Closing test file handle")
                    self.funkyserver._open_file_handle.close()
                    self.funkyserver._open_file_handle = None
                    assert os.path.exists(f)
                    os.remove(f)
                    assert not os.path.exists(f)
                    return "OK"
            except Exception as e:
                logging.error(
                    "Failed to close file handle and delete file: %s\n%s", e,
                    _traceback_str())
                return "FAIL"
        if self.path.startswith('/stop'):
            logging.info("Returning child_processes_terminated: %r",
                         self.funkyserver.child_processes_terminated)
            return repr(self.funkyserver.child_processes_terminated)
        return "OK"
Esempio n. 4
0
    def SvcDoRun(self):
        if hasattr(sys, "frozen"):
            this_dir = os.path.dirname(win32api.GetModuleFileName(None))
        else:
            this_dir = os.path.dirname(os.path.abspath(__file__))
        # TODO: maybe it is better to run this in a job object too
        with open(os.path.join(this_dir, 'npm.log'), 'w') as npm_log:
            subprocess.check_call('npm install',
                                  cwd=this_dir,
                                  shell=True,
                                  stdin=None,
                                  stdout=npm_log,
                                  stderr=subprocess.STDOUT)

        security_attributes = win32security.SECURITY_ATTRIBUTES()
        security_attributes.bInheritHandle = True
        startup = win32process.STARTUPINFO()
        startup.dwFlags |= win32process.STARTF_USESTDHANDLES
        startup.hStdInput = None
        startup.hStdOutput = win32file.CreateFile(
            os.path.join(this_dir, "service_stderr.log"),
            win32file.GENERIC_WRITE, win32file.FILE_SHARE_READ,
            security_attributes, win32file.CREATE_ALWAYS, 0, None)
        startup.hStdError = win32file.CreateFile(
            os.path.join(this_dir, "service_stdout.log"),
            win32file.GENERIC_WRITE, win32file.FILE_SHARE_READ,
            security_attributes, win32file.CREATE_ALWAYS, 0, None)
        (hProcess, hThread, processId, threadId) = win32process.CreateProcess(
            None, r'"C:\Program Files\nodejs\node.exe" node_worker.js', None,
            None, True, win32process.CREATE_SUSPENDED
            | win32process.CREATE_BREAKAWAY_FROM_JOB, None, this_dir, startup)

        assert not win32job.IsProcessInJob(hProcess, None)

        self.hJob = win32job.CreateJobObject(None, "")
        extended_info = win32job.QueryInformationJobObject(
            self.hJob, win32job.JobObjectExtendedLimitInformation)
        extended_info['BasicLimitInformation'][
            'LimitFlags'] = win32job.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE | win32job.JOB_OBJECT_LIMIT_BREAKAWAY_OK
        win32job.SetInformationJobObject(
            self.hJob, win32job.JobObjectExtendedLimitInformation,
            extended_info)
        win32job.AssignProcessToJobObject(self.hJob, hProcess)

        win32process.ResumeThread(hThread)
        win32api.CloseHandle(hThread)

        signalled = win32event.WaitForMultipleObjects(
            [self.hWaitStop, hProcess], False, win32event.INFINITE)
        if signalled == win32event.WAIT_OBJECT_0 + 1 and win32process.GetExitCodeProcess(
                hProcess) != 0:
            servicemanager.LogErrorMsg(
                self._svc_name_ + " process exited with non-zero status " +
                str(win32process.GetExitCodeProcess(hProcess)))
        win32api.CloseHandle(hProcess)
        win32api.CloseHandle(self.hJob)
        win32api.CloseHandle(self.hWaitStop)
        win32api.CloseHandle(startup.hStdOutput)
        win32api.CloseHandle(startup.hStdError)
Esempio n. 5
0
def assign_job(hjob):
    global g_hjob
    hprocess = win32api.GetCurrentProcess()
    try:
        win32job.AssignProcessToJobObject(hjob, hprocess)
        g_hjob = hjob
    except win32job.error as e:
        if (e.winerror != winerror.ERROR_ACCESS_DENIED
                or sys.getwindowsversion() >= (6, 2)
                or not win32job.IsProcessInJob(hprocess, None)):
            raise
        warnings.warn('The process is already in a job. Nested jobs are not '
                      'supported prior to Windows 8.')
Esempio n. 6
0
    def job(self) -> WIN32JOB:
        """Get the job associated with this process.

        Caches between calls for safety.

        Returns
        -------
        WIN32JOB
            A Windows job which consists of one or more processes. In this case
            we just have the one process
        """
        if not hasattr(self, "_job"):

            # First try to import stuff, an easy exception to catch and give good
            # information about
            try:
                import win32api
                import win32job
                import winerror
            except ModuleNotFoundError as e:
                raise ModuleNotFoundError(_win32_import_error_msg) from e

            # Here, we assign it to a windows "Job", whatever that is
            # If the process is already assigned to a job, then we have
            # to check if it's less than Windows 8 because apparently
            # nested jobs aren't supported there
            try:
                job = win32job.CreateJobObject(None, "")

                process = win32api.GetCurrentProcess()
                win32job.AssignProcessToJobObject(job, process)

                self._job = job

            except win32job.error as e:
                if (e.winerror != winerror.ERROR_ACCESS_DENIED
                        or sys.getwindowsversion() >= (6, 2)  # type: ignore
                        or not win32job.IsProcessInJob(process, None)):
                    raise e

                msg = ("The process is already in a job."
                       " Nested jobs are not supported prior to Windows 8.")
                raise RuntimeError(msg) from e

        return self._job
Esempio n. 7
0
        job_info = win32job.QueryInformationJobObject(
            job_object, win32job.JobObjectExtendedLimitInformation)

        # Set up the job object so that closing the last handle to the job object
        # will terminate all associated processes and destroy the job object itself.
        job_info["BasicLimitInformation"]["LimitFlags"] |= \
                win32job.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE

        # Update the limits of the job object.
        win32job.SetInformationJobObject(
            job_object, win32job.JobObjectExtendedLimitInformation, job_info)

        return job_object

    # Don't create a job object if the current process is already inside one.
    if win32job.IsProcessInJob(win32process.GetCurrentProcess(), None):
        _JOB_OBJECT = None
    else:
        _JOB_OBJECT = _init_job_object()
        atexit.register(win32api.CloseHandle, _JOB_OBJECT)


class Process(object):
    """Wrapper around subprocess.Popen class."""

    # pylint: disable=protected-access

    def __init__(self, logger, args, env=None, env_vars=None):
        """Initialize the process with the specified logger, arguments, and environment."""

        # Ensure that executable files that don't already have an
Esempio n. 8
0
    cad_job_driver = CADJobDriver(args.assembler, args.mesher, args.analyzer,
                                  args.mode)
    # cad_job_driver = CADJobDriver('ASSEMBLY_EXISTS', args.mesher, args.analyzer, args.mode, False)
    # cad_job_driver = CADJobDriver(args.assembler, args.mesher, args.analyzer, args.mode, False)


if __name__ == '__main__':
    import win32api
    import win32job
    hProcess = win32api.GetCurrentProcess()

    def os_supports_nested_jobs():
        "Nested jobs were introduced in Windows 8 and Windows Server 2012"
        return sys.getwindowsversion()[0:2] >= (6, 2)

    if not win32job.IsProcessInJob(hProcess,
                                   None) or os_supports_nested_jobs():
        hJob = win32job.CreateJobObject(None, "")
        extended_info = win32job.QueryInformationJobObject(
            hJob, win32job.JobObjectExtendedLimitInformation)
        extended_info['BasicLimitInformation'][
            'LimitFlags'] = win32job.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE | win32job.JOB_OBJECT_LIMIT_BREAKAWAY_OK
        win32job.SetInformationJobObject(
            hJob, win32job.JobObjectExtendedLimitInformation, extended_info)
        win32job.AssignProcessToJobObject(hJob, hProcess)
        # n.b. intentionally leak hJob. Otherwise, when running on Windows Server 2008R2 SP1, AssignProcessToJobObject closes hJob (try !handle
        # in windbg before and after), and we crash with invalid handle in CloseHandle on exit
        hJob.Detach()

    main()
Esempio n. 9
0
    command_line = "\"" + get_python_exe(
    ) + "\" scripts\simulate.py --tool Dymola"
    sa = win32security.SECURITY_ATTRIBUTES()
    sa.bInheritHandle = True
    startup = win32process.STARTUPINFO()
    startup.dwFlags += win32process.STARTF_USESTDHANDLES
    startup.hStdError = startup.hStdOutput = win32file.CreateFile(
        "test_dymola_output.txt", win32file.GENERIC_WRITE, 0, sa,
        win32file.CREATE_ALWAYS, win32file.FILE_ATTRIBUTE_NORMAL, None)
    startup.hStdInput = win32api.GetStdHandle(win32api.STD_INPUT_HANDLE)

    (hProcess, hThread, processId, threadId) = win32process.CreateProcess(
        None, command_line, None, None, True,
        win32process.CREATE_BREAKAWAY_FROM_JOB, None, None, startup)

    assert not win32job.IsProcessInJob(hProcess, None)

    hJob = win32job.CreateJobObject(None, "")
    extended_info = win32job.QueryInformationJobObject(
        hJob, win32job.JobObjectExtendedLimitInformation)
    extended_info['BasicLimitInformation'][
        'LimitFlags'] = win32job.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE
    win32job.SetInformationJobObject(
        hJob, win32job.JobObjectExtendedLimitInformation, extended_info)
    win32job.AssignProcessToJobObject(hJob, hProcess)

    status = win32event.WaitForSingleObject(hProcess, 45000)
    win32api.CloseHandle(startup.hStdError)
    if status == win32event.WAIT_TIMEOUT:
        print "Dymola timed out. Likely the license could not be acquired"
        sys.exit(2)