用python在windows上运行os.path.islink

时间:2013-03-06 21:32:34

标签: python windows symlink pywin32

在Windows 7上使用Python 2.7如何检测路径是否为符号链接? 这不起作用os.path.islink(),它说它返回false,如果为false或不支持,我提供的路径肯定是一个符号链接,所以我假设它不支持在Windows上?我该怎么办?

5 个答案:

答案 0 :(得分:20)

根本问题是你使用的是旧版本的Python。如果你想坚持2.x,你将无法利用2010年初之后添加的新功能。

其中一项功能是处理NTFS符号链接。该功能于2010年底在3.2中添加。(有关详细信息,请参阅3.23.12.7来源。)

之前Python没有处理NTFS符号链接的原因是直到2009年底都没有这样的事情。(IIRC,支持包含在6.0内核中,但用户空间支持需要Vista / 2008上的服务包;只有7 / 2008R2和更新版本内置它。此外,您需要一个足够新的MSVCRT才能访问该用户空间支持,并且Python有明确的策略,即不在次要版本中升级到新的Visual Studio版本。)

代码未被移植回2.x的原因是that there will never be a 2.8,而像2.7.3(或2.7.4)这样的错误修复版本没有获得新功能,只有错误修复。

这已被报告为issue 13143,目的是修改2.7文档以澄清islink始终在Windows上返回False

因此,如果您想在Windows下阅读NTFS符号链接,请升级到Python 3.2+,或者您必须使用win32apictypes等自行完成。

或者,正如Martijn Pieters建议的那样,不要自己动手,而是使用像jaraco.windows这样的第三方库来做和/或借用their code

或者,如果您真的想要,请从3.2源代码中借用代码并围绕它构建一个C扩展模块。如果您从ntpath追溯到osnt(实际上是posixmodule.c),我相信它的内容在win32_xstat_impl and win32_xstat_impl_w

答案 1 :(得分:5)

这是我最终用来确定文件或目录是否是Windows 7中的链接:

def isLink(path):
    if os.path.exists(path):
        if os.path.isdir(path):
            FILE_ATTRIBUTE_REPARSE_POINT = 0x0400
            attributes = ctypes.windll.kernel32.GetFileAttributesW(unicode(path))
            return (attributes & FILE_ATTRIBUTE_REPARSE_POINT) > 0
        else:
            command = ['dir', path]
            try:
                with open(os.devnull, 'w') as NULL_FILE:
                    o0 = check_output(command, stderr=NULL_FILE, shell=True)
            except CalledProcessError as e:
                print e.output
                return False
            o1 = [s.strip() for s in o0.split('\n')]
            if len(o1) < 6:
                return False
            else:
                return 'SYMLINK' in o1[5]
    else:
        return False

编辑:根据Zitrax和Annan的建议修改代码

答案 2 :(得分:5)

目录:

    public class ddd
{

    JFrame frame = new JFrame();
    JPanel leftPane = new JPanel();
    JPanel rightPane = new JPanel();
    JTextArea textArea = new JTextArea();
    JButton button = new JButton("LOL");
    JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);


    public ddd()
    {
    /** __COMPONENT OBJECTS__ **/


    splitPane.setLeftComponent(leftPane);
    splitPane.setRightComponent(rightPane);
    splitPane.setLayout(null);
//  splitPane.setSize(frame.getWidth(), frame.getHeight() - menuBar.getHeight());
    splitPane.setVisible(true);
//  splitPane.setLocation(0, menuBar.getHeight());

    /** __RIGHTPANE-PROPS__ **/
    rightPane.add(textArea);
    rightPane.setSize(500, 100);
    rightPane.setVisible(true);


    /** __LEFTPANE-PROPS__ **/
    leftPane.add(button);
    leftPane.setSize(100, 100);
    leftPane.setVisible(true);

    /** __FRAME-PROPS__ **/
    frame.add(splitPane);
    frame.setLayout(new GridLayout());
    frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    frame.setSize(500, 400);
    frame.setVisible(true);
    }

    public static void main(String[] args)
    {
    new ddd();
    }
}

Source

答案 3 :(得分:0)

仅使用if file[-4:len(file)] != ".lnk":对我有用

答案 4 :(得分:0)

您还可以使用pywin32模块:GetFileAttributes子模块中的win32apiFILE_ATTRIBUTE_REPARSE_POINT模块中的win32con都是可用的。例如,要测试给定路径是否为目录的符号链接,代码将变为:

import os
import win32api
import win32con

def is_directory_symlink(path):
    return bool(os.path.isdir(path) 
                and (win32api.GetFileAttributes(path) &
                     win32con.FILE_ATTRIBUTE_REPARSE_POINT))

如果使用Python 2,并且路径可能包含非ASCII字符,则GetFileAttributes需要一个unicode字符串。但是,仅使用unicode(path)通常会失败:您应该测试path是否为str,如果是,则使用其decode方法。