Python 实现 popocat 回收站图标更换

1. 前提准备/思路记录(思考过程,乱!)

刚开始各种搜索引擎,博客,搜集资料,前期准备,下面的步骤还是后期优化过的,刚开始是记录各种有用的,思路很乱,代码可以直接看后面的,成品自取

通过桌面【右击】—>【个性化】—>【主题】—>【桌面图标设置】—>【更改图标】可以查看到默认的默认图标是 imageres.dll,这是 windos 默认的图标库。
在这里插入图片描述
Win 10 风格的图标库有:

  1. ddores.dll
  2. dmdskres.dll
  3. imageres.dll
  4. mmres.dll
  5. networkexplorer.dll
  6. pnidui.dll
  7. sensorscpl.dll
  8. setupapi.dll
  9. shell32.dll
  10. wmploc.dll
  11. wpdshext.dll

更多可以参考博客:Windos 图标 dll

1.1. 思路记录

刚开始什么都不知道的时候,想着,编写程序自动替换该 dll,调用网站转换图标格式:转换 ico 然后编写程序运行即可;
程序主要分为以下部分:

  1. 替换 dll
  2. 调用网站转换图标格式【可选】,也可通过程序调用
  3. 自动生成新的 dll【难度较大,可选】emmmm,不算很大,可以参考博文(C++)
  4. 修改注册表,更新回收站的值
  5. 桌面图标注册表对应项

1.2. pythonmagick

第三方模块(刚开始想写 GUI,找到了 TKInterDesigner,但是有 BUG,我的电脑用不了,暂且搁置):

pythonmagick,不能 pip install,需要手动 下载,注意甄别版本以及CPU架构(通过命令查看 pip debug --verbose,我的是 cp38-cp38-win_amd64)!cp10对应的 python 版本3.10,cp38 对应 python 版本3.8

import PythonMagick

img = PythonMagick.Image("logo.png")  # 加载需要转换的图片
img.sample('64x64')  # 设置生成的 icon 的大小
img.write("logo.ico") # 生成 icon 并保存

回收站图标所在位置

  1. 【还原】回收站默认图标的位置:HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{645FF040-5081-101B-9F08-00AA002F954E}\DefaultIcon
  2. 【更改】回收站自定义图标的位置:HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\CLSID\{645FF040-5081-101B-9F08-00AA002F954E}\DefaultIcon

目录下的项 emptyfull 的值分别对应回收站空和满(非空)的时候的 icon 图标位置;

  • 如果在注册表 [HKEY_CURRENT_USER\Software\Classes\CLSID](WIN9X)[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\CLSID](WIN2000/XP) 中定义了某系统文件夹的图标或名称,它的优先级将高于[HKEY_CLASSES_ROOT\CLSID]。桌面上的我的电脑、我的文档、网上邻居等图标和名称均在此定义。
  • 项的值的类型都是 REG_EXPAND_SZ,数据分别是:
    • (默认):%SystemRoot%\System32\imageres.dll,-55
    • Empty:%SystemRoot%\System32\imageres.dll,-55
    • Full:%SystemRoot%\System32\imageres.dll,-54

2. 代码分析

2.1. ICO 图标转换

将 icons 文件夹下的图片转换为 ico 文件并存储在 iocn 文件夹下;

import os
import PythonMagick


def get_files():
    filenames = os.listdir(os.path.join(os.getcwd(), 'icons'))
    for index, item in enumerate(filenames):
        filenames[index] = './icons/' + item
    return filenames


def convert(sava_path):
    if not os.path.exists(sava_path) or os.path.isfile(sava_path):
        os.mkdir(sava_path)
    else:
        os.mkdir(sava_path)
    filenames = get_files()
    for item in filenames:
        img = PythonMagick.Image(item)  # 加载需要转换的图片
        img.sample('256x256')  # 设置生成的 icon 的大小
        img.write('./icon/' + item[8:len(item) - 3] + 'ico')  # 生成 icon 并保存


if __name__ == '__main__':
    convert("icon")

2.2. 生成 dll

这里我是通过 VS 新建一个动态链接库项目,然后导入上一步骤的 ico 文件,之后生成即可。也可以直接把 ico 后缀改成 dll,这样的话下一步的代码相关逻辑也需要改变一点点。

  1. 创建动态链接库项目
    在这里插入图片描述
  2. 添加资源文件(ico 图标)
    在这里插入图片描述
  3. 生成 dll
    在这里插入图片描述
  4. 从生成的路径下将 dll 复制(剪贴也行)一份备用。

2.3. 修改注册表

dll 文件需要存储在本地,所以选择存储在了 TEMP 文件夹下,存储在其他文件夹下也可以,不建议存储在 system32 下。

import os
import winreg

dll_name = "cookie_icon.dll"
dll_dir_path = os.path.join(os.getenv("TEMP"), "{645FF040-5081-101B-9F08-00AA002F954E}")
dll_file_path = os.path.join(dll_dir_path, dll_name)
key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, r"Software\\Microsoft\\Windows\\CurrentVersion\\"
                                               r"Explorer\\CLSID\\{645FF040-5081-101B-9F08-00AA002F954E}"
                                               r"\\DefaultIcon", 0, winreg.KEY_ALL_ACCESS)
try:
    winreg.SetValueEx(key, "empty", 0, winreg.REG_EXPAND_SZ, dll_file_path + ",0")
    winreg.SetValueEx(key, "full", 0, winreg.REG_EXPAND_SZ, dll_file_path + ",1")
    print("更换成功~双击回收站后查看效果")
    # TODO: 加入刷新机制,刷新一下桌面,实现后无需点回收站就可以看到图标更新效果
    # 目前网上找到的大部分都是 taskkill explorer.exe 然后重启,会导致桌面短暂卡死,产生僵尸进程
    os.system("pause")
except WindowsError as e:
    print("WindowsError: " + e)
finally:
    winreg.CloseKey(key)

3. 成果展示

成果!我的大力!!!呜呜~

在这里插入图片描述

4. 资源分享

已经将相关代码打包成 exe了,直接运行即可(仅限 Windows),mac 没玩过,不知道,略。链接自取

使用 pyinstaller 打包:

pyinstaller -F -i ./popocat_full.ico popocat.py

生成单文件 exe,但是没法将外部文件打包进 exe 中,有自解压可以打包进去,但是达不到想要的效果。

于是百度发现了 Enigma Virtual Box 打包软件。
在这里插入图片描述
打包后的 exe 自取

5. 总结

虽然实际代码看上去很短,但是确实不去了解的话真写不出来,先是选择 Java,发现貌似操作系统底层还是得 C 语言,换成 C 语言后写出来了,但是句柄什么的写得我头疼,最后发现了 winreg 这个 python 库,确实好用,把许多无用(严谨点来说,是不常用)的参数都封装起来了。
在这里插入图片描述

人没事就得多折腾,折腾得多了,寿命也就没了。


版权声明:本文为Xbai_hang原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。