Обнаружение символических ссылок (mklink) в Vista / 7 в Python без Pywin32 - PullRequest
4 голосов
/ 21 сентября 2009

В настоящее время для создания символических ссылок в сборочном рецепте colle.recipe.omelette используется файл junction.exe во всех версиях Windows. Однако junction.exe не поставляется с Windows по умолчанию и, что важнее всего, не поддерживает создание символических ссылок на файлы (только каталоги), что вызывает проблемы с довольно большим количеством пакетов Python.

В NT6 + (Vista и 7) теперь есть утилита mklink, которая не только поставляется по умолчанию, но и способна создавать символические ссылки на файлы и каталоги. Я хотел бы обновить файл collect.recipe.omelette, чтобы использовать его, если он доступен, и сделал это, за исключением одной простой функции; определение, является ли файл или папка символической ссылкой Поскольку это небольшой рецепт сборки, требовать Pywin32, на мой взгляд, слишком много (разве что setuptools может каким-то образом загрузить его только в Windows?).

В настоящее время в Windows омлет выполняет вызов junction.exe для папки, а затем вызывает запрос «Замените имя:», но я не могу найти ничего более простого для mklink.

Единственный метод, который я могу придумать, - это вызвать в каталоге «dir», а затем пройти строку ответа за строкой в ​​поисках «» и папки / имени файла в той же строке. Неужели есть что-то лучше?

Ответы [ 5 ]

5 голосов
/ 24 октября 2009

См. jaraco.windows.filesystem (часть пакета jaraco.windows ) для подробных примеров операций с символьными ссылками в Windows без pywin32.

3 голосов
/ 21 сентября 2009

Не могли бы вы использовать ctypes для доступа к различным необходимым функциям и структурам? этот патч , который в настоящее время обсуждается, предназначен для добавления функциональности символической ссылки к модулю os в Vista и Windows 7, но не будет до Python 2.7 и 3.2, поэтому ожидание (и требование к самым последним версиям, когда они в конце концов появятся), вероятно, будет слишком длинным; решение на основе ctypes может перевернуть вас, и код в патче покажет, что для этого требуется на C (а программирование на Python на основе ctypes только немного сложнее, чем то же программирование на C).

Если кто-то уже не выпустил какую-либо другую автономную утилиту, например junction.exe, для этой цели я не вижу других работоспособных подходов (пока этот патч окончательно не превратится в stdlib будущего Python) помимо использования ctypes, Pywin32 или dir, и вы уже исключили последние два из этих трех вариантов ...! -)

2 голосов
/ 21 сентября 2009

В окнах соединения и символические ссылки имеют атрибут FILE_ATTRIBUTE_REPARSE_POINT (0x400) для точек повторной обработки. Если вы получили атрибуты файла, то обнаружите это на?

Вы можете использовать ctypes (как указано в другом ответе) для доступа к Kernel32.dll и GetFileAttributes и обнаружить это значение.

0 голосов
/ 05 октября 2018

Я широко искал лучшее решение, однако Python 2.7 просто не имеет хорошего решения для этого. Так что в конце концов, я закончил с этим (код ниже), он, по общему признанию, уродлив, но это довольно симпатично по сравнению со всеми взломами ctypes, которые я видел.

import os, subprocess

def realpath(path):
    # not a folder path, ignore
    if (not os.path.isdir(path)):
        return path

    rootpath = os.path.abspath(path)
    oneup, foldername = os.path.split(rootpath)
    output = subprocess.check_output("dir " + oneup, shell=True)

    links = {}
    for line in output.splitlines():
        pos = line.find("<SYMLINKD>")
        if not pos == -1:
            link = line[pos+15:].split()
            links[link[0]] = link[1].strip("[]")
    return links[foldername] if links.has_key(foldername) else rootpath
0 голосов
/ 06 января 2011

Вы можете использовать имеющийся у вас Tcl с Tkinter, так как он имеет команду 'file link', которая знает о соединениях, в отличие от модуля Pythons os.

...