1

在python中确定Windows夹路径的最佳方法是什么?

我发现了一些适用于 SpecialFolders 的流行方法,即CSIDL,但对于KNOWNFOLDERID 来说还没有什么简单的方法。保持向后兼容性,因此 CSIDL 方法仍然有效,但自 Windows XP 以来引入的任何特殊/已知文件夹都不会在此处枚举。“新”不可用的示例包括下载、播放列表、程序文件 x64。

特殊文件夹

  • 在 Python 中查找系统文件夹位置- 最简单的 CSIDL 方法,依赖于 win32com,适用于AllUsersDesktop、AllUsersStartMenu、AllUsersPrograms、AllUsersStartup、Desktop、Favorites、Fonts、MyDocuments、NetHood、PrintHood、Recent、SendTo、StartMenu、Startup & Templates (列表可能不完整)。

  • 如何获取开始菜单的程序目录的路径?- 具有与上述相同的方法,以及直接使用 ctypes 的方法,因此不需要 win32com(不清晰或直接)

已知文件夹

  • ?

两者合一

  • ?
4

1 回答 1

2

你解决这个问题的方法和那个问题一样:首先你找到文档和最好的 C++、C# 或 VB 中的一些很好的示例代码,然后你弄清楚如何使用 PyWin32IKnownFolder从 Python 进行相同的 shell API 或 COM 调用。

正如关于Known Folders的 MSDN 概述文档所说,您可以使用新的 shell 包装函数SHGetKnownFolderPath而不是旧的SHFolderPathor SHGetFolderPath,或者您可以IKnownFolderManager通过 COM 使用完整的接口。

不幸的是,我面前没有一台 Windows 机器,而且 MSDN 的示例下载没有响应,所以我将不得不做一些猜测。但它可能是这样的:

from win32com.shell import shell, shellcon
path = shell.SHGetKnownFolderPath(shellcon.FOLDERID_AccountPictures,
                                  0, # see KNOWN_FOLDER_FLAG
                                  0) # current user

如果shellcon没有这些FOLDERID值,则必须在 上查找它们KNOWNFOLDERID并自己定义所需的常量。

如果shell没有该SHGetKnownFolderPath功能,则必须实例化 anIKnownFolderManager并调用GetFolderByName.

如果shell甚至没有IKnownFolderManager……但是快速的 Google 显示它是在 build 218 中添加的,所以这不会成为问题。


如果你宁愿通过ctypesthan来做win32com,它看起来像这样(再次,未经测试,因为我没有 Windows 机器并且 MSDN 的服务器坏了):

from ctypes import windll, wintypes
from ctypes import *
from uuid import UUID

# ctypes GUID copied from MSDN sample code
class GUID(Structure):
    _fields_ = [
        ("Data1", wintypes.DWORD),
        ("Data2", wintypes.WORD),
        ("Data3", wintypes.WORD),
        ("Data4", wintypes.BYTE * 8)
    ] 

    def __init__(self, uuidstr):
        uuid = UUID(uuidstr)
        Structure.__init__(self)
        self.Data1, self.Data2, self.Data3, self.Data4[0], self.Data4[1], rest = uuid.fields
        for i in range(2, 8):
            self.Data4[i] = rest>>(8-i-1)*8 & 0xff

FOLDERID_AccountPictures = '{008ca0b1-55b4-4c56-b8a8-4de4b299d3be}'

SHGetKnownFolderPath = windll.shell32.SHGetKnownFolderPath
SHGetKnownFolderPath.argtypes = [
    POINTER(GUID), wintypes.DWORD, wintypes.HANDLE, POINTER(c_char_p)]

def get_known_folder_path(uuidstr):
    pathptr = c_wchar_p()
    guid = GUID(uuidstr)
    if SHGetKnownFolderPath(byref(guid), 0, 0, byref(pathptr)):
        raise Exception('Whatever you want here...')
    return pathptr.value
于 2015-04-27T06:34:43.483 回答