~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/win32utils.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2010-05-28 00:25:32 UTC
  • mfrom: (5264.1.2 command-help-bug-177500)
  • Revision ID: pqm@pqm.ubuntu.com-20100528002532-9bzj1fajyxckd1rg
(lifeless) Stop raising at runtime when a command has no help,
 instead have a test in the test suite that checks all known command objects.
 (Robert Collins)

Show diffs side-by-side

added added

removed removed

Lines of Context:
468
468
 
469
469
 
470
470
def get_app_path(appname):
471
 
    r"""Look up in Windows registry for full path to application executable.
 
471
    """Look up in Windows registry for full path to application executable.
472
472
    Typically, applications create subkey with their basename
473
473
    in HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\
474
474
 
522
522
            trace.mutter('Unable to set hidden attribute on %r: %s', path, e)
523
523
 
524
524
 
525
 
def _command_line_to_argv(command_line, argv, single_quotes_allowed=False):
 
525
def _command_line_to_argv(command_line, single_quotes_allowed=False):
526
526
    """Convert a Unicode command line into a list of argv arguments.
527
527
 
528
528
    It performs wildcard expansion to make wildcards act closer to how they
535
535
                                  default.
536
536
    :return: A list of unicode strings.
537
537
    """
538
 
    # First, spit the command line
539
538
    s = cmdline.Splitter(command_line, single_quotes_allowed=single_quotes_allowed)
540
 
    
541
 
    # Bug #587868 Now make sure that the length of s agrees with sys.argv 
542
 
    # we do this by simply counting the number of arguments in each. The counts should 
543
 
    # agree no matter what encoding sys.argv is in (AFAIK) 
544
 
    # len(arguments) < len(sys.argv) should be an impossibility since python gets 
545
 
    # args from the very same PEB as does GetCommandLineW
546
 
    arguments = list(s)
547
 
    
548
 
    # Now shorten the command line we get from GetCommandLineW to match sys.argv
549
 
    if len(arguments) < len(argv):
550
 
        raise AssertionError("Split command line can't be shorter than argv")
551
 
    arguments = arguments[len(arguments) - len(argv):]
552
 
    
553
 
    # Carry on to process globs (metachars) in the command line
554
 
    # expand globs if necessary
 
539
    # Now that we've split the content, expand globs if necessary
555
540
    # TODO: Use 'globbing' instead of 'glob.glob', this gives us stuff like
556
541
    #       '**/' style globs
557
542
    args = []
558
 
    for is_quoted, arg in arguments:
 
543
    for is_quoted, arg in s:
559
544
        if is_quoted or not glob.has_magic(arg):
560
545
            args.append(arg)
561
546
        else:
572
557
        if command_line is None:
573
558
            raise ctypes.WinError()
574
559
        # Skip the first argument, since we only care about parameters
575
 
        argv = _command_line_to_argv(command_line, sys.argv)[1:]
 
560
        argv = _command_line_to_argv(command_line)[1:]
 
561
        if getattr(sys, 'frozen', None) is None:
 
562
            # Invoked via 'python.exe' which takes the form:
 
563
            #   python.exe [PYTHON_OPTIONS] C:\Path\bzr [BZR_OPTIONS]
 
564
            # we need to get only BZR_OPTIONS part,
 
565
            # We already removed 'python.exe' so we remove everything up to and
 
566
            # including the first non-option ('-') argument.
 
567
            for idx in xrange(len(argv)):
 
568
                if argv[idx][:1] != '-':
 
569
                    break
 
570
            argv = argv[idx+1:]
576
571
        return argv
577
572
else:
578
573
    get_unicode_argv = None
579
 
 
580
 
 
581
 
if has_win32api:
582
 
    def _pywin32_is_local_pid_dead(pid):
583
 
        """True if pid doesn't correspond to live process on this machine"""
584
 
        try:
585
 
            handle = win32api.OpenProcess(1, False, pid) # PROCESS_TERMINATE
586
 
        except pywintypes.error, e:
587
 
            if e[0] == 5: # ERROR_ACCESS_DENIED
588
 
                # Probably something alive we're not allowed to kill
589
 
                return False
590
 
            elif e[0] == 87: # ERROR_INVALID_PARAMETER
591
 
                return True
592
 
            raise
593
 
        handle.close()
594
 
        return False
595
 
    is_local_pid_dead = _pywin32_is_local_pid_dead
596
 
elif has_ctypes and sys.platform == 'win32':
597
 
    from ctypes.wintypes import BOOL, DWORD, HANDLE
598
 
    _kernel32 = ctypes.windll.kernel32
599
 
    _CloseHandle = ctypes.WINFUNCTYPE(BOOL, HANDLE)(
600
 
        ("CloseHandle", _kernel32))
601
 
    _OpenProcess = ctypes.WINFUNCTYPE(HANDLE, DWORD, BOOL, DWORD)(
602
 
        ("OpenProcess", _kernel32))
603
 
    def _ctypes_is_local_pid_dead(pid):
604
 
        """True if pid doesn't correspond to live process on this machine"""
605
 
        handle = _OpenProcess(1, False, pid) # PROCESS_TERMINATE
606
 
        if not handle:
607
 
            errorcode = ctypes.GetLastError()
608
 
            if errorcode == 5: # ERROR_ACCESS_DENIED
609
 
                # Probably something alive we're not allowed to kill
610
 
                return False
611
 
            elif errorcode == 87: # ERROR_INVALID_PARAMETER
612
 
                return True
613
 
            raise ctypes.WinError(errorcode)
614
 
        _CloseHandle(handle)
615
 
        return False
616
 
    is_local_pid_dead = _ctypes_is_local_pid_dead