コード例 #1
0
def _win32_symlink(path, link, verbose=0):
    """
    Creates real symlink. This will only work in versions greater than Windows
    Vista. Creating real symlinks requires admin permissions or at least
    specially enabled symlink permissions. On Windows 10 enabling developer
    mode should give you these permissions.
    """
    from ubelt import util_cmd
    if os.path.isdir(path):
        # directory symbolic link
        if verbose:
            print('... as directory symlink')
        command = 'mklink /D "{}" "{}"'.format(link, path)
        # Using the win32 API seems to result in privilege errors
        # but using shell commands does not have this problem. Weird.
        # jwfs.symlink(path, link, target_is_directory=True)
        # TODO: what do we need to do to use the windows api instead of shell?
    else:
        # file symbolic link
        if verbose:
            print('... as file symlink')
        command = 'mklink "{}" "{}"'.format(link, path)

    if command is not None:
        info = util_cmd.cmd(command, shell=True)
        if info['ret'] != 0:
            from ubelt import util_format
            permission_msg = 'You do not have sufficient privledges'
            if permission_msg not in info['err']:
                print('Failed command:')
                print(info['command'])
                print(util_format.repr2(info, nl=1))
            raise OSError(str(info))
    return link
コード例 #2
0
def _win32_dir(path, star=''):
    """
    Using the windows cmd shell to get information about a directory
    """
    from ubelt import util_cmd
    import re
    wrapper = 'cmd /S /C "{}"'  # the /S will preserve all inner quotes
    command = 'dir /-C "{}"{}'.format(path, star)
    wrapped = wrapper.format(command)
    info = util_cmd.cmd(wrapped, shell=True)
    if info['ret'] != 0:
        from ubelt import util_format
        print('Failed command:')
        print(info['command'])
        print(util_format.repr2(info, nl=1))
        raise OSError(str(info))
    # parse the output of dir to get some info
    # Remove header and footer
    lines = info['out'].split('\n')[5:-3]
    splitter = re.compile('( +)')
    for line in lines:
        parts = splitter.split(line)
        date, sep, time, sep, ampm, sep, type_or_size, sep = parts[:8]
        name = ''.join(parts[8:])
        # if type is a junction then name will also contain the linked loc
        if name == '.' or name == '..':
            continue
        if type_or_size in ['<JUNCTION>', '<SYMLINKD>', '<SYMLINK>']:
            # colons cannot be in path names, so use that to find where
            # the name ends
            pos = name.find(':')
            bpos = name[:pos].rfind('[')
            name = name[:bpos - 1]
            pointed = name[bpos + 1:-1]
            yield type_or_size, name, pointed
        else:
            yield type_or_size, name, None
コード例 #3
0
def _win32_junction(path, link, verbose=0):
    """
    On older (pre 10) versions of windows we need admin privledges to make
    symlinks, however junctions seem to work.

    For paths we do a junction (softlink) and for files we use a hard link

    Example:
        >>> # xdoc: +REQUIRES(WIN32)
        >>> import ubelt as ub
        >>> root = ub.ensure_app_cache_dir('ubelt', 'win32_junction')
        >>> ub.delete(root)
        >>> ub.ensuredir(root)
        >>> fpath = join(root, 'fpath.txt')
        >>> dpath = join(root, 'dpath')
        >>> fjunc = join(root, 'fjunc.txt')
        >>> djunc = join(root, 'djunc')
        >>> ub.touch(fpath)
        >>> ub.ensuredir(dpath)
        >>> ub.ensuredir(join(root, 'djunc_fake'))
        >>> ub.ensuredir(join(root, 'djunc_fake with space'))
        >>> ub.touch(join(root, 'djunc_fake with space file'))
        >>> _win32_junction(fpath, fjunc)
        >>> _win32_junction(dpath, djunc)
        >>> # thank god colons are not allowed
        >>> djunc2 = join(root, 'djunc2 [with pathological attrs]')
        >>> _win32_junction(dpath, djunc2)
        >>> _win32_is_junction(djunc)
        >>> ub.writeto(join(djunc, 'afile.txt'), 'foo')
        >>> assert ub.readfrom(join(dpath, 'afile.txt')) == 'foo'
        >>> ub.writeto(fjunc, 'foo')
    """
    # junctions store absolute paths
    path = os.path.abspath(path)
    link = os.path.abspath(link)

    from ubelt import util_cmd
    if os.path.isdir(path):
        # try using a junction (soft link)
        if verbose:
            print('... as soft link')

        # TODO: what is the windows api for this?
        command = 'mklink /J "{}" "{}"'.format(link, path)
    else:
        # try using a hard link
        if verbose:
            print('... as hard link')
        # command = 'mklink /H "{}" "{}"'.format(link, path)
        try:
            jwfs.link(path, link)  # this seems to be allowed
        except Exception:
            print('Failed to hardlink link={} to path={}'.format(link, path))
            raise
        command = None

    if command is not None:
        info = util_cmd.cmd(command, shell=True)
        if info['ret'] != 0:
            from ubelt import util_format
            print('Failed command:')
            print(info['command'])
            print(util_format.repr2(info, nl=1))
            raise OSError(str(info))
    return link