【问题标题】:How to change folder icons with Python on windows?如何在 Windows 上使用 Python 更改文件夹图标?
【发布时间】:2011-01-11 21:15:57
【问题描述】:

我想编写一个实用程序脚本来更改具有特定名称的文件夹的图标。这在 python 中可行吗?如果没有,有没有其他方法可以做到这一点?

谢谢

【问题讨论】:

    标签: python windows winapi


    【解决方案1】:
    import os
    import ctypes
    from ctypes import POINTER, Structure, c_wchar, c_int, sizeof, byref
    from ctypes.wintypes import BYTE, WORD, DWORD, LPWSTR, LPSTR
    import win32api    
    
    HICON = c_int
    LPTSTR = LPWSTR
    TCHAR = c_wchar
    MAX_PATH = 260
    FCSM_ICONFILE = 0x00000010
    FCS_FORCEWRITE = 0x00000002
    SHGFI_ICONLOCATION = 0x000001000    
    
    class GUID(Structure):
        _fields_ = [
            ('Data1', DWORD),
            ('Data2', WORD),
            ('Data3', WORD),
            ('Data4', BYTE * 8)]
    
    class SHFOLDERCUSTOMSETTINGS(Structure):
        _fields_ = [
            ('dwSize', DWORD),
            ('dwMask', DWORD),
            ('pvid', POINTER(GUID)),
            ('pszWebViewTemplate', LPTSTR),
            ('cchWebViewTemplate', DWORD),
            ('pszWebViewTemplateVersion', LPTSTR),
            ('pszInfoTip', LPTSTR),
            ('cchInfoTip', DWORD),
            ('pclsid', POINTER(GUID)),
            ('dwFlags', DWORD),
            ('pszIconFile', LPTSTR),
            ('cchIconFile', DWORD),
            ('iIconIndex', c_int),
            ('pszLogo', LPTSTR),
            ('cchLogo', DWORD)]
    
    class SHFILEINFO(Structure):
        _fields_ = [
            ('hIcon', HICON),
            ('iIcon', c_int),
            ('dwAttributes', DWORD),
            ('szDisplayName', TCHAR * MAX_PATH),
            ('szTypeName', TCHAR * 80)]    
    
    def seticon(folderpath, iconpath, iconindex):
        """Set folder icon.
    
        >>> seticon(".", "C:\\Windows\\system32\\SHELL32.dll", 10)
    
        """
        shell32 = ctypes.windll.shell32
    
        folderpath = unicode(os.path.abspath(folderpath), 'mbcs')
        iconpath = unicode(os.path.abspath(iconpath), 'mbcs')
    
        fcs = SHFOLDERCUSTOMSETTINGS()
        fcs.dwSize = sizeof(fcs)
        fcs.dwMask = FCSM_ICONFILE
        fcs.pszIconFile = iconpath
        fcs.cchIconFile = 0
        fcs.iIconIndex = iconindex
    
        hr = shell32.SHGetSetFolderCustomSettings(byref(fcs), folderpath,
                                                  FCS_FORCEWRITE)
        if hr:
            raise WindowsError(win32api.FormatMessage(hr))
    
        sfi = SHFILEINFO()
        hr = shell32.SHGetFileInfoW(folderpath, 0, byref(sfi), sizeof(sfi),
                                    SHGFI_ICONLOCATION)
        if hr == 0:
            raise WindowsError(win32api.FormatMessage(hr))
    
        index = shell32.Shell_GetCachedImageIndexW(sfi.szDisplayName, sfi.iIcon, 0)
        if index == -1:
            raise WindowsError()
    
        shell32.SHUpdateImageW(sfi.szDisplayName, sfi.iIcon, 0, index)
    

    【讨论】:

    • 我不知道如何让它再次工作,但它在 Python 3.x 中不起作用——“unicode”已被弃用,如果我注释掉这两个,我会得到一个 OSError行。
    【解决方案2】:

    据我了解,要做到这一点必须Customise Folders with Desktop.ini。虽然this question 上可能有更多信息。

    【讨论】:

    • 太棒了,这正是我想要的。我所要做的就是生成那个文件,我猜windows会选择它。非常感谢!
    • 不完全。文件属性必须包括 System 和 Hidden,如果不更新图标缓存,Windows 可能无法显示正确的图标。
    • @Waldo,期待 Windows 做事是一个危险的习惯;)但我希望我能帮上忙。
    • 通过 ctypes 更好地使用 SHGetSetFolderCustomSettings 和 SHChangeNotify API 函数。
    • @William 参考了哪个版本的 desktop.ini,简单搜索 C 盘已返回 2020 年 9 月最新版本的 desktop.ini 的 65 个结果
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-23
    • 1970-01-01
    • 2013-10-21
    • 2012-09-23
    • 1970-01-01
    • 2012-03-08
    • 1970-01-01
    相关资源
    最近更新 更多