在不使用 Pywin32 的情况下在 Python 中检测 Vista/7 上的符号链接 (mklink)

发布于 2024-08-04 20:16:30 字数 583 浏览 6 评论 0原文

目前,构建配方 Collective.recipe.omelette 在所有版本的 Windows 上使用 junction.exe 来创建符号链接。然而,junction.exe 默认情况下不随 Windows 一起提供,最重要的是不支持创建文件(仅目录)的符号链接,这会导致相当多的 Python 包出现问题。

在 NT6+(Vista 和 7)上,现在有 mklink 实用程序,它不仅是默认提供的,而且还能够创建文件和目录的符号链接。我想更新 Collective.recipe.omelette 以使用此功能(如果可用),并且除了一项简单的功能外,我已经这样做了;检测文件或文件夹是否实际上是符号链接。由于这是一个小型构建方案,因此在我看来需要 Pywin32 有点太多了(除非 setuptools 只能在 Windows 上下载它?)。

目前在 Windows 上,omelette 的作用是在文件夹上调用 junction.exe,然后 grep 响应“Substitute Name:”,但我找不到 mklink 那样简单的内容。

我能想到的唯一方法是在目录中调用“dir”,然后逐行浏览响应以查找“”和文件夹/文件名在同一行。肯定有更好的东西吗?

Currently the buildout recipe collective.recipe.omelette uses junction.exe on all versions of Windows to create symlinks. However junction.exe does not come with Windows by default and most importantly does not support creating symlinks to files (only directories) which causes a problem with quite a few Python packages.

On NT6+ (Vista and 7) there is now the mklink utility that not only comes by default but is also capable of creating symlinks to files as well as directories. I would like to update collective.recipe.omelette to use this if available and have done so except for one otherwise simple feature; detecting whether a file or folder is actually a symlink. Since this is a small buildout recipe, requiring Pywin32 in my opinion is a bit too much (unless setuptools could somehow only download it on Windows?).

Currently on Windows what omelette does is call junction.exe on the folder and then grep the response for "Substitute Name:" but I can't find anything as simple for mklink.

The only method I can think of is to call "dir" in the directory and then to go through the response line by line looking for "<SYMLINK>" and the folder/filename on the same line. Surely there is something better?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

丶情人眼里出诗心の 2024-08-11 20:16:30

请参阅 jaraco.windows.filesystemjaraco.windows 包的一部分)有关 Windows 中符号链接操作的详细示例,无需pywin32。

See jaraco.windows.filesystem (part of the jaraco.windows package) for extensive examples on symlink operations in Windows without pywin32.

泼猴你往哪里跑 2024-08-11 20:16:30

您可以使用ctypes来访问各种所需的函数和结构吗? 此补丁目前正在讨论中,旨在添加符号链接Vista 和 Windows 7 下的模块 os 功能 - 但它不会出现在 Python 2.7 和 3.2 之前,因此需要等待(以及最终出现时对最新版本的要求)可能太长;基于 ctypes 的解决方案可能会让您渡过难关,补丁中的代码显示了在 C 中需要做什么(并且在 Python 中基于 ctypes 的编程只比在 C 中进行相同的编程难一点) )。

除非有人已经为此目的发布了一些其他独立的实用程序,例如junction.exe,否则除了使用ctypes之外,我看不到其他可行的方法(直到该补丁最终将其纳入未来的Python的stdlib), Pywin32 或 dir,并且您已经排除了这三个选项中的最后两个...!-)

Could you use ctypes to access the various needed functions and structures? this patch, currently under discussion, is intended to add symlink functionality to module os under Vista and Windows 7 -- but it won't be in before Python 2.7 and 3.2, so the wait (and the requirement for the very latest versions when they do eventually come) will likely be too long; a ctypes-based solution might tide you over and the code in the patch shows what it takes in C to do it (and ctypes-based programmed in Python is only a bit harder than the same programming in C).

Unless somebody's already released some other stand-alone utility like junction.exe for this purpose, I don't see other workable approaches (until that patch finally makes it into a future Python's stdlib) beyond using ctypes, Pywin32, or dir, and you've already ruled out the last two of these three options...!-)

乜一 2024-08-11 20:16:30

在 Windows 上,连接和符号链接具有用于重分析点的属性 FILE_ATTRIBUTE_REPARSE_POINT (0x400)。如果你得到了文件的属性,那么检测这个?

您可以使用 ctypes (如其他答案中所述)访问 Kernel32.dll 和 GetFileAttributes,并检测该值。

On windows junctions and symbolic links have the attribute FILE_ATTRIBUTE_REPARSE_POINT (0x400) for reparse points. If you get the file's attributes, then detect this on?

You could use ctypes (as stated in the other answer) to access Kernel32.dll and GetFileAttributes, and detect this value.

怪我鬧 2024-08-11 20:16:30

您可以利用 Tkinter 提供的 Tcl,因为它有一个了解连接的“文件链接”命令,这与 Python 的 os 模块不同。

You could leverage the Tcl you have available with Tkinter, as that has a 'file link' command that knows about junctions, unlike Pythons os module.

葬﹪忆之殇 2024-08-11 20:16:30

我广泛搜索了更好的解决方案,但是 python 2.7 对此没有一个好的解决方案。所以最终,我最终得到了这个(下面的代码),它确实很难看,但与我见过的所有 ctypes hack 相比,它是非常漂亮的。

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

I have searched widely for a better solution, however python 2.7 just does not have a good solution for this. So eventually, I ended up with this (code below), its admittedly ugly, but it's downright pretty compared to all the ctypes hacks I've seen.

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文