文章目录
1. 前提准备/思路记录(思考过程,乱!)
刚开始各种搜索引擎,博客,搜集资料,前期准备,下面的步骤还是后期优化过的,刚开始是记录各种有用的,思路很乱,代码可以直接看后面的,成品自取
通过桌面【右击】—>【个性化】—>【主题】—>【桌面图标设置】—>【更改图标】可以查看到默认的默认图标是 imageres.dll,这是 windos 默认的图标库。
Win 10 风格的图标库有:
ddores.dlldmdskres.dllimageres.dllmmres.dllnetworkexplorer.dllpnidui.dllsensorscpl.dllsetupapi.dllshell32.dllwmploc.dllwpdshext.dll
更多可以参考博客:Windos 图标 dll
1.1. 思路记录
刚开始什么都不知道的时候,想着,编写程序自动替换该 dll,调用网站转换图标格式:转换 ico 然后编写程序运行即可;
程序主要分为以下部分:
- 替换 dll
- 调用网站转换图标格式【可选】,也可通过程序调用
- 自动生成新的 dll【难度较大,可选】emmmm,不算很大,可以参考博文(C++)
- 修改注册表,更新回收站的值
- 桌面图标注册表对应项
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 并保存
- 【还原】回收站默认图标的位置:
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{645FF040-5081-101B-9F08-00AA002F954E}\DefaultIcon - 【更改】回收站自定义图标的位置:
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\CLSID\{645FF040-5081-101B-9F08-00AA002F954E}\DefaultIcon
目录下的项
empty、full的值分别对应回收站空和满(非空)的时候的 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,这样的话下一步的代码相关逻辑也需要改变一点点。
- 创建动态链接库项目

- 添加资源文件(ico 图标)

- 生成 dll

- 从生成的路径下将 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 库,确实好用,把许多无用(严谨点来说,是不常用)的参数都封装起来了。
人没事就得多折腾,折腾得多了,寿命也就没了。