原创内容,转载请注明出处:https://www.myzhenai.com.cn/post/4810.html
我有个习惯,我会偶尔使用360安全卫士,只用它里边有软件管家进行升级,一用完我就会卸载360安全卫士
我知道360安全卫士会在系统盘中残留很多目录、文件,同时它有一些sys驱动文件会残留在系统重要目录中
同时注册表中也会残留非常多的数据
当你卸载了360安全卫士后,这些东西还保存在你的系统之中
我不知道为什么360官方开发人员为什么不在卸载程序中删除这些残留文件
程序和源代码下载:
通过网盘分享的文件:360cleaner
链接: https://pan.baidu.com/s/14gZYAsjnpnOIahAMKBtTnA?pwd=25xy 提取码: 25xy
–来自百度网盘超级会员v10的分享
以下是我找到的360给我们系统中残留下来的一些目录、文件、注册表信息
C:\360SANDBOX\ C:\$360Section\ C:\Program Files (x86)\360\ C:\ProgramData\360safe\ C:\ProgramData\360SD\ C:\Users\All Users\360safe\ C:\Users\All Users\360SD\ C:\Users\RucLinuxs\AppData\LocalLow\360WD\ C:\Users\RucLinuxs\AppData\Roaming\360DesktopLite\ C:\Users\RucLinuxs\AppData\Roaming\360Login\ C:\Users\RucLinuxs\AppData\Roaming\360Quarant\ C:\Users\RucLinuxs\AppData\Roaming\360Safe\ C:\Windows\Tasks\360Disabled\ C:\Windows\System32\drivers\360AntiHacker64.sys C:\Windows\System32\drivers\360AntiHijack64.sys C:\Windows\System32\drivers\360AntiSteal64.sys C:\Windows\System32\drivers\360Box64.sys C:\Windows\System32\drivers\360Camera64.sys C:\Windows\System32\drivers\360elam64.sys C:\Windows\System32\drivers\360FsFlt.sys C:\Windows\System32\drivers\360Hvm64.dat C:\Windows\System32\drivers\360Hvm64.sys C:\Windows\System32\drivers\360netmon.sys C:\Windows\System32\drivers\360qpesv64.sys C:\Windows\System32\drivers\360Sensor64.sys 计算机\HKEY_CLASSES_ROOT\*\shellex\ContextMenuHandlers\Safe360Ext 计算机\HKEY_CLASSES_ROOT\.360SafeUAP 计算机\HKEY_CLASSES_ROOT\360Safe.ext.1 计算机\HKEY_CLASSES_ROOT\360SafeLive.Update 计算机\HKEY_CLASSES_ROOT\360SafeLive.Update.2 计算机\HKEY_CLASSES_ROOT\AppID\shell360ext.DLL 计算机\HKEY_CLASSES_ROOT\CLSID\{039219EC-5F9A-460E-8C72-86D5DC7B8683}\DefaultIcon 计算机\HKEY_CLASSES_ROOT\CLSID\{039219EC-5F9A-460E-8C72-86D5DC7B8683}\InprocServer32 计算机\HKEY_CLASSES_ROOT\CLSID\{039219EC-5F9A-460E-8C72-86D5DC7B8683}\Shell\Open 计算机\HKEY_CLASSES_ROOT\CLSID\{056A6FBD-8148-443A-AAB2-DB3C46B1F083}\DefaultIcon 计算机\HKEY_CLASSES_ROOT\CLSID\{056A6FBD-8148-443A-AAB2-DB3C46B1F083}\InprocServer32 计算机\HKEY_CLASSES_ROOT\CLSID\{056A6FBD-8148-443A-AAB2-DB3C46B1F083}\Shell\Open 计算机\HKEY_CLASSES_ROOT\CLSID\{06F2A2CA-E0E2-47D7-A3EC-29FD090E7F86}\DefaultIcon 计算机\HKEY_CLASSES_ROOT\CLSID\{06F2A2CA-E0E2-47D7-A3EC-29FD090E7F86}\InprocServer32 计算机\HKEY_CLASSES_ROOT\CLSID\{06F2A2CA-E0E2-47D7-A3EC-29FD090E7F86}\Shell\Open 计算机\HKEY_CLASSES_ROOT\CLSID\{12793398-A212-446F-BA1E-1F1B5ABDB89C}\DefaultIcon 计算机\HKEY_CLASSES_ROOT\CLSID\{12793398-A212-446F-BA1E-1F1B5ABDB89C}\InprocServer32 计算机\HKEY_CLASSES_ROOT\CLSID\{12793398-A212-446F-BA1E-1F1B5ABDB89C}\Shell\Open 计算机\HKEY_CLASSES_ROOT\CLSID\{12DE9E3C-5119-424b-93A5-D72E3D005558}\DefaultIcon 计算机\HKEY_CLASSES_ROOT\CLSID\{12DE9E3C-5119-424b-93A5-D72E3D005558}\Shell\Delete\Command 计算机\HKEY_CLASSES_ROOT\CLSID\{12DE9E3C-5119-424b-93A5-D72E3D005558}\Shell\Open\Command 计算机\HKEY_CLASSES_ROOT\CLSID\{26CD0715-0722-479B-A8C7-29A911171774}\InProcServer32 计算机\HKEY_CLASSES_ROOT\CLSID\{2A650B6F-1548-4294-AB07-F17604108156}\DefaultIcon 计算机\HKEY_CLASSES_ROOT\CLSID\{2A650B6F-1548-4294-AB07-F17604108156}\InprocServer32 计算机\HKEY_CLASSES_ROOT\CLSID\{2A650B6F-1548-4294-AB07-F17604108156}\Shell\Open 计算机\HKEY_CLASSES_ROOT\CLSID\{47F57C45-E7A1-4414-A6F0-A0865F6E4CA6}\DefaultIcon 计算机\HKEY_CLASSES_ROOT\CLSID\{47F57C45-E7A1-4414-A6F0-A0865F6E4CA6}\InprocServer32 计算机\HKEY_CLASSES_ROOT\CLSID\{47F57C45-E7A1-4414-A6F0-A0865F6E4CA6}\Shell\Open 计算机\HKEY_CLASSES_ROOT\CLSID\{4D88ED58-E7F0-4EF2-AE06-5D5873AD19C6}\DefaultIcon 计算机\HKEY_CLASSES_ROOT\CLSID\{4D88ED58-E7F0-4EF2-AE06-5D5873AD19C6}\InprocServer32 计算机\HKEY_CLASSES_ROOT\CLSID\{4D88ED58-E7F0-4EF2-AE06-5D5873AD19C6}\Shell\Open 计算机\HKEY_CLASSES_ROOT\CLSID\{55F9A4E2-52B3-4743-9EA7-2FEE413DABB6}\DefaultIcon 计算机\HKEY_CLASSES_ROOT\CLSID\{55F9A4E2-52B3-4743-9EA7-2FEE413DABB6}\InprocServer32 计算机\HKEY_CLASSES_ROOT\CLSID\{55F9A4E2-52B3-4743-9EA7-2FEE413DABB6}\Shell\Open 计算机\HKEY_CLASSES_ROOT\CLSID\{5E19C0CE-C02C-46c2-98C3-A2E12EDE0E17} 计算机\HKEY_CLASSES_ROOT\CLSID\{63A39D0C-0B63-49EE-BB21-D106ED548C51}\DefaultIcon 计算机\HKEY_CLASSES_ROOT\CLSID\{63A39D0C-0B63-49EE-BB21-D106ED548C51}\InprocServer32 计算机\HKEY_CLASSES_ROOT\CLSID\{63A39D0C-0B63-49EE-BB21-D106ED548C51}\Shell\Open 计算机\HKEY_CLASSES_ROOT\CLSID\{645FF040-5081-101B-9F08-00AA002F954E}\shell\深度清理垃圾 计算机\HKEY_CLASSES_ROOT\CLSID\{645FF040-5081-101B-9F08-00AA002F954E}\shell\深度清理垃圾\command 计算机\HKEY_CLASSES_ROOT\CLSID\{6A377734-9D9D-44AE-A69C-06E81F6C8064}\DefaultIcon 计算机\HKEY_CLASSES_ROOT\CLSID\{6A377734-9D9D-44AE-A69C-06E81F6C8064}\InprocServer32 计算机\HKEY_CLASSES_ROOT\CLSID\{6A377734-9D9D-44AE-A69C-06E81F6C8064}\Shell\Open 计算机\HKEY_CLASSES_ROOT\CLSID\{6bd299cd-1997-4cc6-834c-e3c1c6ba0ea5}\InprocServer32 计算机\HKEY_CLASSES_ROOT\CLSID\{78A1990F-7561-4CB9-A8BF-B6CCF8AAEB97}\InprocServer32 计算机\HKEY_CLASSES_ROOT\CLSID\{7A148181-CEB9-4F5E-B5F2-CDC5B68BD3A8}\DefaultIcon 计算机\HKEY_CLASSES_ROOT\CLSID\{7A148181-CEB9-4F5E-B5F2-CDC5B68BD3A8}\InprocServer32 计算机\HKEY_CLASSES_ROOT\CLSID\{7A148181-CEB9-4F5E-B5F2-CDC5B68BD3A8}\Shell\Open 计算机\HKEY_CLASSES_ROOT\CLSID\{7C0F6D57-E799-4C8A-A319-8E2B4D724CF0}\InprocServer32 计算机\HKEY_CLASSES_ROOT\CLSID\{826D8B56-A99E-4CD2-8F38-CFCE2A7B89C4}\DefaultIcon 计算机\HKEY_CLASSES_ROOT\CLSID\{826D8B56-A99E-4CD2-8F38-CFCE2A7B89C4}\InprocServer32 计算机\HKEY_CLASSES_ROOT\CLSID\{826D8B56-A99E-4CD2-8F38-CFCE2A7B89C4}\Shell\Open 计算机\HKEY_CLASSES_ROOT\CLSID\{86A06468-8A7C-4EFA-A61C-9C0E911194C9}\DefaultIcon 计算机\HKEY_CLASSES_ROOT\CLSID\{86A06468-8A7C-4EFA-A61C-9C0E911194C9}\InprocServer32 计算机\HKEY_CLASSES_ROOT\CLSID\{86A06468-8A7C-4EFA-A61C-9C0E911194C9}\Shell\Open 计算机\HKEY_CLASSES_ROOT\CLSID\{A0AB8231-8E73-410D-8D1C-BE1027EA19A3}\DefaultIcon 计算机\HKEY_CLASSES_ROOT\CLSID\{A0AB8231-8E73-410D-8D1C-BE1027EA19A3}\InprocServer32 计算机\HKEY_CLASSES_ROOT\CLSID\{A0AB8231-8E73-410D-8D1C-BE1027EA19A3}\Shell\Open 计算机\HKEY_CLASSES_ROOT\CLSID\{A23CB8EB-C9C4-475D-88C0-CC51933F2D9E}\DefaultIcon 计算机\HKEY_CLASSES_ROOT\CLSID\{A23CB8EB-C9C4-475D-88C0-CC51933F2D9E}\InprocServer32 计算机\HKEY_CLASSES_ROOT\CLSID\{A23CB8EB-C9C4-475D-88C0-CC51933F2D9E}\Shell\Open 计算机\HKEY_CLASSES_ROOT\CLSID\{AF1859F5-DF30-4EEC-9404-E5F32FD260B7}\DefaultIcon 计算机\HKEY_CLASSES_ROOT\CLSID\{AF1859F5-DF30-4EEC-9404-E5F32FD260B7}\InprocServer32 计算机\HKEY_CLASSES_ROOT\CLSID\{AF1859F5-DF30-4EEC-9404-E5F32FD260B7}\Shell\Open 计算机\HKEY_CLASSES_ROOT\CLSID\{C0B3184D-90C8-4F4D-B19A-42B6C659378B}\DefaultIcon 计算机\HKEY_CLASSES_ROOT\CLSID\{C0B3184D-90C8-4F4D-B19A-42B6C659378B}\InprocServer32 计算机\HKEY_CLASSES_ROOT\CLSID\{C0B3184D-90C8-4F4D-B19A-42B6C659378B}\Shell\Open 计算机\HKEY_CLASSES_ROOT\CLSID\{C9A94B6A-60FB-4A19-8BA3-4A2068F1026D}\DefaultIcon 计算机\HKEY_CLASSES_ROOT\CLSID\{C9A94B6A-60FB-4A19-8BA3-4A2068F1026D}\InprocServer32 计算机\HKEY_CLASSES_ROOT\CLSID\{C9A94B6A-60FB-4A19-8BA3-4A2068F1026D}\Shell\Open 计算机\HKEY_CLASSES_ROOT\CLSID\{CC00F81D-5262-450A-B1FA-D6BEE3406263} 计算机\HKEY_CLASSES_ROOT\CLSID\{CC00F81D-5262-450A-B1FA-D6BEE3406263}\InprocServer32 计算机\HKEY_CLASSES_ROOT\CLSID\{D1FD8167-E560-4B08-9F4E-CA89F979BD84} 计算机\HKEY_CLASSES_ROOT\CLSID\{D1FD8167-E560-4B08-9F4E-CA89F979BD84}\InprocServer32 计算机\HKEY_CLASSES_ROOT\CLSID\{D8A9DF39-075A-4C8C-B48B-8121C37FFDF0}\DefaultIcon 计算机\HKEY_CLASSES_ROOT\CLSID\{D8A9DF39-075A-4C8C-B48B-8121C37FFDF0}\InprocServer32 计算机\HKEY_CLASSES_ROOT\CLSID\{D8A9DF39-075A-4C8C-B48B-8121C37FFDF0}\Shell\Open 计算机\HKEY_CLASSES_ROOT\CLSID\{E431A037-AE60-4D57-99D7-B402223AE8A0}\DefaultIcon 计算机\HKEY_CLASSES_ROOT\CLSID\{E431A037-AE60-4D57-99D7-B402223AE8A0}\InprocServer32 计算机\HKEY_CLASSES_ROOT\CLSID\{E431A037-AE60-4D57-99D7-B402223AE8A0}\Shell\Open 计算机\HKEY_CLASSES_ROOT\CLSID\{E715FE74-087F-4F4C-BB0A-0245C8A897E2}\DefaultIcon 计算机\HKEY_CLASSES_ROOT\CLSID\{E715FE74-087F-4F4C-BB0A-0245C8A897E2}\InprocServer32 计算机\HKEY_CLASSES_ROOT\CLSID\{E715FE74-087F-4F4C-BB0A-0245C8A897E2}\Shell\Open 计算机\HKEY_CLASSES_ROOT\CLSID\{EE3F69E2-3085-4C46-B050-A45F008827D6}\DefaultIcon 计算机\HKEY_CLASSES_ROOT\CLSID\{EE3F69E2-3085-4C46-B050-A45F008827D6}\InprocServer32 计算机\HKEY_CLASSES_ROOT\CLSID\{EE3F69E2-3085-4C46-B050-A45F008827D6}\Shell\Open 计算机\HKEY_CLASSES_ROOT\CLSID\{EEE8C32E-C785-4B1F-A33B-FCD6942418BD}\DefaultIcon 计算机\HKEY_CLASSES_ROOT\CLSID\{EEE8C32E-C785-4B1F-A33B-FCD6942418BD}\InprocServer32 计算机\HKEY_CLASSES_ROOT\CLSID\{EEE8C32E-C785-4B1F-A33B-FCD6942418BD}\Shell\Open 计算机\HKEY_CLASSES_ROOT\CLSID\{F6BC477E-2646-459A-9D6A-75902C24430D}\DefaultIcon 计算机\HKEY_CLASSES_ROOT\CLSID\{F6BC477E-2646-459A-9D6A-75902C24430D}\InprocServer32 计算机\HKEY_CLASSES_ROOT\CLSID\{F6BC477E-2646-459A-9D6A-75902C24430D}\Shell\Open 计算机\HKEY_CLASSES_ROOT\CLSID\{FA1B1706-967F-4834-8405-2343A38E4086}\DefaultIcon 计算机\HKEY_CLASSES_ROOT\CLSID\{FA1B1706-967F-4834-8405-2343A38E4086}\InprocServer32 计算机\HKEY_CLASSES_ROOT\CLSID\{FA1B1706-967F-4834-8405-2343A38E4086}\Shell\Open 计算机\HKEY_CLASSES_ROOT\CLSID\{FD6A8A28-DB7F-478C-A358-C989EFE02096}\DefaultIcon 计算机\HKEY_CLASSES_ROOT\CLSID\{FD6A8A28-DB7F-478C-A358-C989EFE02096}\InprocServer32 计算机\HKEY_CLASSES_ROOT\CLSID\{FD6A8A28-DB7F-478C-A358-C989EFE02096}\Shell\Open 计算机\HKEY_CLASSES_ROOT\Folder\ShellEx\ContextMenuHandlers\Safe360Ext 计算机\HKEY_CLASSES_ROOT\lnkfile\shellex\ContextMenuHandlers\Safe360Ext 计算机\HKEY_CLASSES_ROOT\Local Settings\Software\Microsoft\Windows\Shell\MuiCache 这里有一些360的键值 计算机\HKEY_CLASSES_ROOT\qsdis\DefaultIcon 计算机\HKEY_CLASSES_ROOT\qsdis\shell\open\command 计算机\HKEY_CLASSES_ROOT\qsoftmgr\shell\open\command 计算机\HKEY_CLASSES_ROOT\softmanager360 计算机\HKEY_CLASSES_ROOT\softmanager360\DefaultIcon 计算机\HKEY_CLASSES_ROOT\softmanager360\Shell\Open\Command 计算机\HKEY_CLASSES_ROOT\TypeLib\{338CE0CA-987B-4CC9-8297-5430E7DCFD2A}\1.0\0\win32 计算机\HKEY_CLASSES_ROOT\TypeLib\{338CE0CA-987B-4CC9-8297-5430E7DCFD2A}\1.0\0\win64 计算机\HKEY_CLASSES_ROOT\TypeLib\{338CE0CA-987B-4CC9-8297-5430E7DCFD2A}\1.0\HELPDIR 计算机\HKEY_CLASSES_ROOT\TypeLib\{42133F20-66FA-4755-9B06-35D6CE360630}\1.0\0\win32 计算机\HKEY_CLASSES_ROOT\TypeLib\{42133F20-66FA-4755-9B06-35D6CE360630}\1.0\HELPDIR 计算机\HKEY_CLASSES_ROOT\TypeLib\{749B9DBD-EBDC-4324-A3C3-95BF9E8234B1}\1.0\0\win32 计算机\HKEY_CLASSES_ROOT\TypeLib\{749B9DBD-EBDC-4324-A3C3-95BF9E8234B1}\1.0\HELPDIR 计算机\HKEY_CLASSES_ROOT\TypeLib\{90FA8B71-C512-4D04-BE3F-3E2CFE7487C1}\1.0\0\win64 计算机\HKEY_CLASSES_ROOT\TypeLib\{90FA8B71-C512-4D04-BE3F-3E2CFE7487C1}\1.0\HELPDIR 计算机\HKEY_CLASSES_ROOT\WOW6432Node\CLSID\{26CD0715-0722-479B-A8C7-29A911171774}\InProcServer32 计算机\HKEY_CLASSES_ROOT\WOW6432Node\CLSID\{467B32FF-C688-40FF-95FC-C7C61247B0AA}\InprocServer32 计算机\HKEY_CLASSES_ROOT\WOW6432Node\CLSID\{7C0F6D57-E799-4C8A-A319-8E2B4D724CF0}\InprocServer32 计算机\HKEY_CLASSES_ROOT\WOW6432Node\CLSID\{87515F61-A66C-4319-A0E0-D416CB8059E3} 计算机\HKEY_CLASSES_ROOT\WOW6432Node\CLSID\{87515F61-A66C-4319-A0E0-D416CB8059E3}\InprocServer32 计算机\HKEY_CLASSES_ROOT\WOW6432Node\CLSID\{87515F61-A66C-4319-A0E0-D416CB8059E3}\ProgID 计算机\HKEY_CLASSES_ROOT\WOW6432Node\CLSID\{87515F61-A66C-4319-A0E0-D416CB8059E3}\VersionIndependentProgID 计算机\HKEY_CLASSES_ROOT\WOW6432Node\TypeLib\{338CE0CA-987B-4CC9-8297-5430E7DCFD2A}\1.0\0\win32 计算机\HKEY_CLASSES_ROOT\WOW6432Node\TypeLib\{338CE0CA-987B-4CC9-8297-5430E7DCFD2A}\1.0\0\win64 计算机\HKEY_CLASSES_ROOT\WOW6432Node\TypeLib\{338CE0CA-987B-4CC9-8297-5430E7DCFD2A}\1.0\HELPDIR 计算机\HKEY_CLASSES_ROOT\WOW6432Node\TypeLib\{42133F20-66FA-4755-9B06-35D6CE360630}\1.0\0\win32 计算机\HKEY_CLASSES_ROOT\WOW6432Node\TypeLib\{42133F20-66FA-4755-9B06-35D6CE360630}\1.0\HELPDIR 计算机\HKEY_CLASSES_ROOT\WOW6432Node\TypeLib\{749B9DBD-EBDC-4324-A3C3-95BF9E8234B1}\1.0\0\win32 计算机\HKEY_CLASSES_ROOT\WOW6432Node\TypeLib\{749B9DBD-EBDC-4324-A3C3-95BF9E8234B1}\1.0\HELPDIR 计算机\HKEY_CLASSES_ROOT\WOW6432Node\TypeLib\{90FA8B71-C512-4D04-BE3F-3E2CFE7487C1}\1.0\0\win64 计算机\HKEY_CLASSES_ROOT\WOW6432Node\TypeLib\{90FA8B71-C512-4D04-BE3F-3E2CFE7487C1}\1.0\HELPDIR 计算机\HKEY_CURRENT_USER\Software 计算机\HKEY_CURRENT_USER\Software\360safe 计算机\HKEY_CURRENT_USER\Software\360se6 计算机\HKEY_CURRENT_USER\Software\360SoftMgr 计算机\HKEY_CURRENT_USER\Software\551c591f-97e9-46bf-909d-9e4f7b016ca9\360qudongdashi 计算机\HKEY_CURRENT_USER\Software\Classes\.360SafeUAP 计算机\HKEY_CURRENT_USER\Software\Classes\360Safe.ext.1 计算机\HKEY_CURRENT_USER\Software\Classes\360Safe.ext.1\shell\open\command 计算机\HKEY_CURRENT_USER\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\MuiCache 这个项下有很多360的键值 计算机\HKEY_CURRENT_USER\Software\Classes\qsdis\shell\open\command 计算机\HKEY_CURRENT_USER\Software\Classes\qsoftmgr\DefaultIcon 计算机\HKEY_CURRENT_USER\Software\Classes\qsoftmgr\shell\open\command 计算机\HKEY_CURRENT_USER\Software\LiveUpdate360 计算机\HKEY_CURRENT_USER\Software\Microsoft\DirectX\UserGpuPreferences 计算机\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FeatureUsage\AppSwitched 这项下有些360的键值 计算机\HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Compatibility Assistant\Store 这项下有些360的键值 计算机\HKEY_CURRENT_USER\Software\MozillaPlugins\@360.cn/360SoftMgrPlugin 计算机\HKEY_CURRENT_USER\Software\MozillaPlugins\@360.cn/360SoftMgrPlugin\MimeTypes\application/360softmgrplugin 计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Classes\*\shellex\ContextMenuHandlers\Safe360Ext 计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Classes\360SafeLive.Update 计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Classes\360SafeLive.Update.2 计算机\HKEY_USERS\360SandBox 计算机\HKEY_USERS\360SPDM
这些东西在用户卸载360后,重启系统照样还能找到
我把这些内容交给了通义千问、Kimi、DeepSeek,让它们生成相应的清理软件
下边我把打包好的软件和源码全发出来,大家可以参考使用
代码运行和打包,请安装以下的包
pip install Pyqt5 pyinstaller pywin32
注:注册表操作风险很高,此次涉及的注册表有其他共用关系,删除前请注意
DeepSeek
import os import sys import winreg import shutil import logging from pathlib import Path from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QCheckBox, QPushButton, QTreeWidget, QTreeWidgetItem, QLabel, QMessageBox, QSplitter, QProgressBar, QFileDialog) from PyQt5.QtCore import Qt, QThread, pyqtSignal from PyQt5.QtGui import QFont # 设置日志 logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') class CleanerThread(QThread): """执行清理工作的线程""" progress_signal = pyqtSignal(int, str) finished_signal = pyqtSignal(bool, str) def __init__(self, items_to_clean): super().__init__() self.items_to_clean = items_to_clean self.total_items = len(items_to_clean) def run(self): success_count = 0 total = self.total_items for i, item in enumerate(self.items_to_clean): item_type, path = item self.progress_signal.emit(int((i / total) * 100), f"处理: {path}") try: if item_type == "file": if os.path.exists(path): os.remove(path) success_count += 1 logging.info(f"已删除文件: {path}") elif item_type == "directory": if os.path.exists(path): shutil.rmtree(path) success_count += 1 logging.info(f"已删除目录: {path}") elif item_type == "registry": try: # 解析注册表路径 if path.startswith("HKEY_CURRENT_USER"): root = winreg.HKEY_CURRENT_USER subkey = path[18:] elif path.startswith("HKEY_LOCAL_MACHINE"): root = winreg.HKEY_LOCAL_MACHINE subkey = path[19:] elif path.startswith("HKEY_CLASSES_ROOT"): root = winreg.HKEY_CLASSES_ROOT subkey = path[18:] else: continue # 删除注册表项 if "\\" in subkey: key_path, value_name = subkey.rsplit("\\", 1) try: key = winreg.OpenKey(root, key_path, 0, winreg.KEY_ALL_ACCESS) winreg.DeleteValue(key, value_name) winreg.CloseKey(key) except FileNotFoundError: pass # 键值不存在,忽略 except WindowsError: # 尝试删除整个项 try: winreg.DeleteKey(root, subkey) except WindowsError: pass # 无法删除,可能需要权限或不存在 else: try: winreg.DeleteKey(root, subkey) except WindowsError: pass # 无法删除,可能需要权限或不存在 success_count += 1 logging.info(f"已处理注册表: {path}") except Exception as e: logging.error(f"处理注册表失败 {path}: {e}") except Exception as e: logging.error(f"处理失败 {path}: {e}") self.progress_signal.emit(100, "清理完成") self.finished_signal.emit(True, f"清理完成! 成功处理 {success_count}/{total} 个项目") class MainWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("360安全卫士残留清理工具") self.setGeometry(100, 100, 900, 600) # 中心部件 central_widget = QWidget() self.setCentralWidget(central_widget) # 主布局 main_layout = QVBoxLayout(central_widget) # 标题 title_label = QLabel("360安全卫士残留清理工具") title_font = QFont() title_font.setPointSize(16) title_font.setBold(True) title_label.setFont(title_font) title_label.setAlignment(Qt.AlignCenter) main_layout.addWidget(title_label) # 说明 desc_label = QLabel("请选择要清理的360安全卫士残留文件和注册表项:") main_layout.addWidget(desc_label) # 创建分割器 splitter = QSplitter(Qt.Vertical) main_layout.addWidget(splitter) # 文件树 self.file_tree = QTreeWidget() self.file_tree.setHeaderLabels(["选择", "类型", "路径"]) self.file_tree.setColumnWidth(0, 100) self.file_tree.setColumnWidth(1, 80) splitter.addWidget(self.file_tree) # 进度区域 progress_widget = QWidget() progress_layout = QVBoxLayout(progress_widget) self.progress_bar = QProgressBar() self.status_label = QLabel("准备就绪") progress_layout.addWidget(self.progress_bar) progress_layout.addWidget(self.status_label) splitter.addWidget(progress_widget) splitter.setSizes([400, 100]) # 按钮区域 button_layout = QHBoxLayout() main_layout.addLayout(button_layout) self.select_all_btn = QPushButton("全选") self.select_all_btn.clicked.connect(self.select_all) button_layout.addWidget(self.select_all_btn) self.deselect_all_btn = QPushButton("全不选") self.deselect_all_btn.clicked.connect(self.deselect_all) button_layout.addWidget(self.deselect_all_btn) self.scan_btn = QPushButton("重新扫描") self.scan_btn.clicked.connect(self.scan_system) button_layout.addWidget(self.scan_btn) self.clean_btn = QPushButton("开始清理") self.clean_btn.clicked.connect(self.start_cleaning) button_layout.addWidget(self.clean_btn) self.export_btn = QPushButton("导出列表") self.export_btn.clicked.connect(self.export_list) button_layout.addWidget(self.export_btn) # 初始化数据 self.clean_items = [] self.scan_system() def scan_system(self): """扫描系统中的360残留""" self.file_tree.clear() self.clean_items = [] # 常见的360残留路径 (基于用户提供的列表) common_paths = [ # 目录 ("directory", "C:\\360SANDBOX\\"), ("directory", "C:\\$360Section\\"), ("directory", "C:\\Program Files (x86)\\360\\"), ("directory", "C:\\ProgramData\\360safe\\"), ("directory", "C:\\ProgramData\\360SD\\"), ("directory", "C:\\Users\\All Users\\360safe\\"), ("directory", "C:\\Users\\All Users\\360SD\\"), ("directory", "C:\\Users\\{}\\AppData\\LocalLow\\360WD\\".format(os.getlogin())), ("directory", "C:\\Users\\{}\\AppData\\Roaming\\360DesktopLite\\".format(os.getlogin())), ("directory", "C:\\Users\\{}\\AppData\\Roaming\\360Login\\".format(os.getlogin())), ("directory", "C:\\Users\\{}\\AppData\\Roaming\\360Quarant\\".format(os.getlogin())), ("directory", "C:\\Users\\{}\\AppData\\Roaming\\360Safe\\".format(os.getlogin())), ("directory", "C:\\Windows\\Tasks\\360Disabled\\"), # 文件 ("file", "C:\\Windows\\System32\\drivers\\360AntiHacker64.sys"), ("file", "C:\\Windows\\System32\\drivers\\360AntiHijack64.sys"), ("file", "C:\\Windows\\System32\\drivers\\360AntiSteal64.sys"), ("file", "C:\\Windows\\System32\\drivers\\360Box64.sys"), ("file", "C:\\Windows\\System32\\drivers\\360Camera64.sys"), ("file", "C:\\Windows\\System32\\drivers\\360elam64.sys"), ("file", "C:\\Windows\\System32\\drivers\\360FsFlt.sys"), ("file", "C:\\Windows\\System32\\drivers\\360Hvm64.sys"), ("file", "C:\\Windows\\System32\\drivers\\360netmon.sys"), ("file", "C:\\Windows\\System32\\drivers\\360qpesv64.sys"), ("file", "C:\\Windows\\System32\\drivers\\360Sensor64.sys"), ] # 常见的360注册表项 registry_paths = [ # 这里添加一部分常见的注册表路径,实际应用中应该更全面 ("registry", "HKEY_CURRENT_USER\\Software\\360safe"), ("registry", "HKEY_CURRENT_USER\\Software\\360se6"), ("registry", "HKEY_CURRENT_USER\\Software\\360SoftMgr"), ("registry", "HKEY_LOCAL_MACHINE\\SOFTWARE\\360safe"), ("registry", "HKEY_LOCAL_MACHINE\\SOFTWARE\\360SD"), ] # 检查项目是否存在并添加到列表 all_items = common_paths + registry_paths for item_type, path in all_items: exists = False if item_type in ["file", "directory"]: exists = os.path.exists(path) elif item_type == "registry": # 简化检查,实际应该尝试打开注册表项 exists = True # 假设存在,让用户决定 if exists or item_type == "registry": # 对于注册表项,即使不确定是否存在也显示 self.add_item_to_tree(item_type, path) self.clean_items.append((item_type, path)) self.status_label.setText("扫描完成。找到 {} 个可能残留的项目".format(len(self.clean_items))) def add_item_to_tree(self, item_type, path): """添加项目到树形控件""" item = QTreeWidgetItem(self.file_tree) item.setCheckState(0, Qt.Checked) # 类型列 item.setText(1, item_type) # 路径列 item.setText(2, path) # 存储原始数据 item.setData(0, Qt.UserRole, (item_type, path)) def select_all(self): """选择所有项目""" for i in range(self.file_tree.topLevelItemCount()): item = self.file_tree.topLevelItem(i) item.setCheckState(0, Qt.Checked) def deselect_all(self): """取消选择所有项目""" for i in range(self.file_tree.topLevelItemCount()): item = self.file_tree.topLevelItem(i) item.setCheckState(0, Qt.Unchecked) def get_selected_items(self): """获取选中的项目""" selected = [] for i in range(self.file_tree.topLevelItemCount()): item = self.file_tree.topLevelItem(i) if item.checkState(0) == Qt.Checked: item_type, path = item.data(0, Qt.UserRole) selected.append((item_type, path)) return selected def start_cleaning(self): """开始清理选中的项目""" selected_items = self.get_selected_items() if not selected_items: QMessageBox.warning(self, "警告", "请先选择要清理的项目") return reply = QMessageBox.question(self, "确认", "即将清理 {} 个项目。此操作不可逆,是否继续?".format(len(selected_items)), QMessageBox.Yes | QMessageBox.No) if reply == QMessageBox.Yes: self.clean_btn.setEnabled(False) self.cleaner_thread = CleanerThread(selected_items) self.cleaner_thread.progress_signal.connect(self.update_progress) self.cleaner_thread.finished_signal.connect(self.cleaning_finished) self.cleaner_thread.start() def update_progress(self, value, message): """更新进度条和状态标签""" self.progress_bar.setValue(value) self.status_label.setText(message) def cleaning_finished(self, success, message): """清理完成后的处理""" self.clean_btn.setEnabled(True) self.status_label.setText(message) QMessageBox.information(self, "完成", message) # 重新扫描系统 self.scan_system() def export_list(self): """导出清理列表到文件""" selected_items = self.get_selected_items() if not selected_items: QMessageBox.warning(self, "警告", "没有选中的项目可导出") return file_path, _ = QFileDialog.getSaveFileName(self, "导出列表", "", "文本文件 (*.txt)") if file_path: try: with open(file_path, 'w', encoding='utf-8') as f: f.write("360安全卫士残留清理列表\n") f.write("=" * 50 + "\n\n") for item_type, path in selected_items: f.write(f"{item_type}: {path}\n") QMessageBox.information(self, "成功", "列表已导出到: {}".format(file_path)) except Exception as e: QMessageBox.critical(self, "错误", "导出失败: {}".format(str(e))) if __name__ == "__main__": # 检查管理员权限 if os.name == 'nt': try: import ctypes if ctypes.windll.shell32.IsUserAnAdmin() == 0: QMessageBox.critical(None, "错误", "此程序需要管理员权限才能运行") sys.exit(1) except: pass app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec_())
通义千问
import os import shutil import winreg import logging from datetime import datetime from PyQt5.QtWidgets import ( QApplication, QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QCheckBox, QGroupBox, QLabel, QScrollArea, QFrame, QMessageBox, QTextEdit, QDialog, QSizePolicy ) from PyQt5.QtCore import Qt, pyqtSignal from PyQt5.QtGui import QFont # ================== 配置 ================== LOG_FILE = "360_cleaner_log.txt" logging.basicConfig( filename=LOG_FILE, level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s", encoding="utf-8" ) # 当前用户名 USERNAME = os.getlogin() # 要清理的目录 DIRECTORIES = [ r"C:\360SANDBOX", r"C:\$360Section", r"C:\Program Files (x86)\360", r"C:\ProgramData\360safe", r"C:\ProgramData\360SD", fr"C:\Users\{USERNAME}\AppData\LocalLow\360WD", fr"C:\Users\{USERNAME}\AppData\Roaming\360DesktopLite", fr"C:\Users\{USERNAME}\AppData\Roaming\360Login", fr"C:\Users\{USERNAME}\AppData\Roaming\360Quarant", fr"C:\Users\{USERNAME}\AppData\Roaming\360Safe", ] # 注册表项 (hkey, subkey, 描述) REGISTRY_ITEMS = [ (winreg.HKEY_CLASSES_ROOT, r"*\\shellex\\ContextMenuHandlers\\Safe360Ext", "右键菜单 - 扫描"), (winreg.HKEY_CLASSES_ROOT, r"Folder\\ShellEx\\ContextMenuHandlers\\Safe360Ext", "右键菜单 - 文件夹扫描"), (winreg.HKEY_CLASSES_ROOT, r"lnkfile\\shellex\\ContextMenuHandlers\\Safe360Ext", "右键菜单 - 快捷方式扫描"), (winreg.HKEY_CLASSES_ROOT, r"qsdis\\shell\\open\\command", "360下载协议"), (winreg.HKEY_CLASSES_ROOT, r"qsoftmgr\\shell\\open\\command", "360软件管家协议"), (winreg.HKEY_CLASSES_ROOT, r"softmanager360\\Shell\\Open\\Command", "软件管家"), (winreg.HKEY_CURRENT_USER, r"Software\\360safe", "用户设置 - 360安全卫士"), (winreg.HKEY_CURRENT_USER, r"Software\\360se6", "用户设置 - 360浏览器"), (winreg.HKEY_CURRENT_USER, r"Software\\360SoftMgr", "用户设置 - 软件管家"), (winreg.HKEY_CURRENT_USER, r"Software\\LiveUpdate360", "用户设置 - 更新"), (winreg.HKEY_CURRENT_USER, r"Software\\MozillaPlugins\\@360.cn/360SoftMgrPlugin", "浏览器插件"), (winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\\Classes\\360SafeLive.Update", "系统更新组件"), (winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\\Classes\\360SafeLive.Update.2", "系统更新组件2"), (winreg.HKEY_USERS, r"360SandBox", "沙箱用户配置"), (winreg.HKEY_USERS, r"360SPDM", "360驱动管理用户"), ] # ================== 工具函数 ================== def is_path_exists(path): return os.path.exists(path) or os.path.isdir(path) def is_reg_key_exists(hkey, subkey): try: reg = winreg.OpenKey(hkey, subkey, 0, winreg.KEY_READ) winreg.CloseKey(reg) return True except: return False def backup_registry_key(hkey, subkey, backup_dir="reg_backup"): os.makedirs(backup_dir, exist_ok=True) safe_subkey = subkey.replace("\\\\", "_").replace("\\", "_") backup_path = os.path.join(backup_dir, f"{safe_subkey}.reg") try: os.system(f'reg export "{hkey_name(hkey)}\\{subkey}" "{backup_path}" >nul 2>&1') logging.info(f"已备份注册表: {subkey} -> {backup_path}") return backup_path except Exception as e: logging.error(f"备份失败 {subkey}: {e}") return None def hkey_name(hkey): return { winreg.HKEY_CLASSES_ROOT: "HKEY_CLASSES_ROOT", winreg.HKEY_CURRENT_USER: "HKEY_CURRENT_USER", winreg.HKEY_LOCAL_MACHINE: "HKEY_LOCAL_MACHINE", winreg.HKEY_USERS: "HKEY_USERS" }.get(hkey, str(hkey)) def delete_directory(path): try: shutil.rmtree(path) logging.info(f"[✓] 删除目录: {path}") return True, "删除成功" except Exception as e: msg = f"删除失败: {e}" logging.error(f"[✗] 删除失败 {path}: {e}") return False, msg def delete_registry_key(hkey, subkey): try: backup_registry_key(hkey, subkey) winreg.DeleteKey(hkey, subkey) logging.info(f"[✓] 删除注册表: {hkey_name(hkey)}\\{subkey}") return True, "删除成功" except Exception as e: msg = f"删除失败: {e}" logging.error(f"[✗] 删除失败 {subkey}: {e}") return False, msg # ================== 日志查看对话框 ================== class LogDialog(QDialog): def __init__(self, parent=None): super().__init__(parent) self.setWindowTitle("清理日志") self.resize(800, 500) layout = QVBoxLayout() self.text_edit = QTextEdit() self.text_edit.setReadOnly(True) self.text_edit.setFont(QFont("Consolas", 9)) if os.path.exists(LOG_FILE): with open(LOG_FILE, 'r', encoding='utf-8') as f: self.text_edit.setText(f.read()) else: self.text_edit.setText("日志文件不存在。") layout.addWidget(self.text_edit) self.setLayout(layout) # ================== 主窗口 ================== class CleanerApp(QWidget): def __init__(self): super().__init__() self.file_checks = {} self.reg_checks = {} self.init_ui() def init_ui(self): self.setWindowTitle("360残留清理助手 (PyQt5版) v1.0") self.resize(900, 700) self.setFont(QFont("微软雅黑", 9)) # 标题 title = QLabel("360安全卫士残留清理工具") title.setFont(QFont("微软雅黑", 16, QFont.Bold)) title.setAlignment(Qt.AlignCenter) title.setStyleSheet("color: darkblue; margin: 10px;") desc = QLabel("请先扫描,然后勾选要删除的项目。") desc.setAlignment(Qt.AlignCenter) desc.setStyleSheet("color: gray; font-size: 12px;") # 按钮行 btn_layout = QHBoxLayout() self.btn_scan = QPushButton("🔍 扫描残留") self.btn_clean = QPushButton("🗑️ 开始清理") self.btn_log = QPushButton("📄 查看日志") self.btn_scan.clicked.connect(self.scan) self.btn_clean.clicked.connect(self.clean) self.btn_log.clicked.connect(self.view_log) for btn in [self.btn_scan, self.btn_clean, self.btn_log]: btn.setMinimumHeight(35) btn.setFont(QFont("微软雅黑", 10)) btn_layout.addWidget(self.btn_scan) btn_layout.addWidget(self.btn_clean) btn_layout.addWidget(self.btn_log) # 状态栏 self.status_label = QLabel("就绪") self.status_label.setStyleSheet("color: blue; padding: 5px;") # 分割线 line = QFrame() line.setFrameShape(QFrame.HLine) line.setFrameShadow(QFrame.Sunken) # 主内容区(滚动) scroll = QScrollArea() scroll.setWidgetResizable(True) scroll_content = QWidget() scroll_layout = QVBoxLayout(scroll_content) # 文件区域 file_group = QGroupBox("📁 文件与目录残留") file_layout = QVBoxLayout() self.file_container = QWidget() self.file_container.setLayout(QVBoxLayout()) file_layout.addWidget(self.file_container) btn_file = QHBoxLayout() self.btn_file_select_all = QPushButton("✅ 全选") self.btn_file_unselect = QPushButton("❌ 取消全选") self.btn_file_select_all.clicked.connect(lambda: self.select_all(self.file_checks, True)) self.btn_file_unselect.clicked.connect(lambda: self.select_all(self.file_checks, False)) btn_file.addWidget(self.btn_file_select_all) btn_file.addWidget(self.btn_file_unselect) btn_file.addStretch() file_layout.addLayout(btn_file) file_group.setLayout(file_layout) # 注册表区域 reg_group = QGroupBox("🪟 注册表残留") reg_layout = QVBoxLayout() self.reg_container = QWidget() self.reg_container.setLayout(QVBoxLayout()) reg_layout.addWidget(self.reg_container) btn_reg = QHBoxLayout() self.btn_reg_select_all = QPushButton("✅ 全选") self.btn_reg_unselect = QPushButton("❌ 取消全选") self.btn_reg_select_all.clicked.connect(lambda: self.select_all(self.reg_checks, True)) self.btn_reg_unselect.clicked.connect(lambda: self.select_all(self.reg_checks, False)) btn_reg.addWidget(self.btn_reg_select_all) btn_reg.addWidget(self.btn_reg_unselect) btn_reg.addStretch() reg_layout.addLayout(btn_reg) reg_group.setLayout(reg_layout) # 添加到主布局 scroll_layout.addWidget(file_group) scroll_layout.addWidget(reg_group) scroll_layout.addStretch() scroll.setWidget(scroll_content) # 主布局 layout = QVBoxLayout() layout.addWidget(title) layout.addWidget(desc) layout.addLayout(btn_layout) layout.addWidget(line) layout.addWidget(scroll) layout.addWidget(self.status_label) self.setLayout(layout) # 初始化状态 self.btn_clean.setEnabled(False) self.btn_log.setEnabled(True) def select_all(self, check_dict, selected): for checkbox in check_dict.values(): checkbox.setChecked(selected) self.status_label.setText(f"已{'全选' if selected else '取消全选'}") def scan(self): # 清空 for i in reversed(range(self.file_container.layout().count())): widget = self.file_container.layout().takeAt(i).widget() if widget: widget.deleteLater() for i in reversed(range(self.reg_container.layout().count())): widget = self.reg_container.layout().takeAt(i).widget() if widget: widget.deleteLater() self.file_checks.clear() self.reg_checks.clear() # 扫描文件 found_file = False for path in DIRECTORIES: if is_path_exists(path): cb = QCheckBox(path) self.file_container.layout().addWidget(cb) self.file_checks[path] = cb found_file = True if not found_file: no_label = QLabel("未发现残留目录") no_label.setStyleSheet("color: green;") self.file_container.layout().addWidget(no_label) # 扫描注册表 found_reg = False for hkey, subkey, desc in REGISTRY_ITEMS: if is_reg_key_exists(hkey, subkey): cb = QCheckBox(f"{hkey_name(hkey)}\\{subkey}") desc_label = QLabel(f" └─ [{desc}]") desc_label.setStyleSheet("color: gray; font-size: 11px; margin-left: 20px;") container = QWidget() v = QVBoxLayout() v.setContentsMargins(0, 0, 0, 0) v.addWidget(cb) v.addWidget(desc_label) container.setLayout(v) self.reg_container.layout().addWidget(container) self.reg_checks[(hkey, subkey)] = (cb, desc) found_reg = True if not found_reg: no_label = QLabel("未发现残留注册表项") no_label.setStyleSheet("color: green;") self.reg_container.layout().addWidget(no_label) total_files = len([c for c in self.file_checks.values() if isinstance(c, QCheckBox)]) total_regs = len([c for c in self.reg_checks.values()]) self.status_label.setText(f"扫描完成,发现文件残留 {total_files} 项,注册表残留 {total_regs} 项。") self.btn_clean.setEnabled(total_files > 0 or total_regs > 0) def clean(self): selected_files = [path for path, cb in self.file_checks.items() if cb.isChecked()] selected_regs = [key for key, (cb, _) in self.reg_checks.items() if cb.isChecked()] if not selected_files and not selected_regs: QMessageBox.information(self, "提示", "没有勾选任何项目。") return reply = QMessageBox.question( self, "确认", f"即将删除 {len(selected_files)} 个目录和 {len(selected_regs)} 个注册表项,是否继续?", QMessageBox.Yes | QMessageBox.No ) if reply != QMessageBox.Yes: return success = 0 fail = 0 # 删除文件 for path in selected_files: ok, _ = delete_directory(path) success += ok fail += not ok # 删除注册表 for (hkey, subkey), (cb, desc) in self.reg_checks.items(): if cb.isChecked(): ok, _ = delete_registry_key(hkey, subkey) success += ok fail += not ok QMessageBox.information(self, "完成", f"清理完成!\n成功: {success}\n失败: {fail}\n日志已保存。") self.status_label.setText(f"清理完成,成功 {success},失败 {fail}") def view_log(self): dialog = LogDialog(self) dialog.exec_() # ================== 启动入口 ================== def main(): import ctypes if not ctypes.windll.shell32.IsUserAnAdmin(): QMessageBox.critical(None, "权限错误", "请以管理员身份运行此程序!") return app = QApplication([]) window = CleanerApp() window.show() app.exec_() if __name__ == "__main__": main()
import os import shutil import winreg import logging from datetime import datetime import tkinter as tk from tkinter import ttk, messagebox, scrolledtext # ================== 配置 ================== LOG_FILE = "360_cleaner_log.txt" logging.basicConfig( filename=LOG_FILE, level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s", encoding="utf-8" ) USERNAME = os.getlogin() DIRECTORIES = [ r"C:\360SANDBOX", r"C:\$360Section", r"C:\Program Files (x86)\360", r"C:\ProgramData\360safe", r"C:\ProgramData\360SD", fr"C:\Users\{USERNAME}\AppData\LocalLow\360WD", fr"C:\Users\{USERNAME}\AppData\Roaming\360DesktopLite", fr"C:\Users\{USERNAME}\AppData\Roaming\360Login", fr"C:\Users\{USERNAME}\AppData\Roaming\360Quarant", fr"C:\Users\{USERNAME}\AppData\Roaming\360Safe", ] REGISTRY_ITEMS = [ (winreg.HKEY_CLASSES_ROOT, r"*\\shellex\\ContextMenuHandlers\\Safe360Ext", "右键菜单 - 扫描"), (winreg.HKEY_CLASSES_ROOT, r"Folder\\ShellEx\\ContextMenuHandlers\\Safe360Ext", "右键菜单 - 文件夹扫描"), (winreg.HKEY_CLASSES_ROOT, r"lnkfile\\shellex\\ContextMenuHandlers\\Safe360Ext", "右键菜单 - 快捷方式扫描"), (winreg.HKEY_CLASSES_ROOT, r"qsdis\\shell\\open\\command", "360下载协议"), (winreg.HKEY_CLASSES_ROOT, r"qsoftmgr\\shell\\open\\command", "360软件管家协议"), (winreg.HKEY_CLASSES_ROOT, r"softmanager360\\Shell\\Open\\Command", "软件管家"), (winreg.HKEY_CURRENT_USER, r"Software\\360safe", "用户设置 - 360安全卫士"), (winreg.HKEY_CURRENT_USER, r"Software\\360se6", "用户设置 - 360浏览器"), (winreg.HKEY_CURRENT_USER, r"Software\\360SoftMgr", "用户设置 - 软件管家"), (winreg.HKEY_CURRENT_USER, r"Software\\LiveUpdate360", "用户设置 - 更新"), (winreg.HKEY_CURRENT_USER, r"Software\\MozillaPlugins\\@360.cn/360SoftMgrPlugin", "浏览器插件"), (winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\\Classes\\360SafeLive.Update", "系统更新组件"), (winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\\Classes\\360SafeLive.Update.2", "系统更新组件2"), (winreg.HKEY_USERS, r"360SandBox", "沙箱用户配置"), (winreg.HKEY_USERS, r"360SPDM", "360驱动管理用户"), ] def is_path_exists(path): return os.path.exists(path) or os.path.isdir(path) def is_reg_key_exists(hkey, subkey): try: reg = winreg.OpenKey(hkey, subkey, 0, winreg.KEY_READ) winreg.CloseKey(reg) return True except: return False def backup_registry_key(hkey, subkey, backup_dir="reg_backup"): os.makedirs(backup_dir, exist_ok=True) backup_path = os.path.join(backup_dir, f"{subkey.replace('\\\\', '_')}.reg") try: os.system(f'reg export "{hkey_name(hkey)}\\{subkey}" "{backup_path}" >nul 2>&1') return backup_path except Exception as e: logging.error(f"备份失败 {subkey}: {e}") return None def hkey_name(hkey): return { winreg.HKEY_CLASSES_ROOT: "HKEY_CLASSES_ROOT", winreg.HKEY_CURRENT_USER: "HKEY_CURRENT_USER", winreg.HKEY_LOCAL_MACHINE: "HKEY_LOCAL_MACHINE", winreg.HKEY_USERS: "HKEY_USERS" }.get(hkey, str(hkey)) def delete_directory(path): try: shutil.rmtree(path) logging.info(f"[✓] 删除目录: {path}") return True, "删除成功" except Exception as e: msg = f"删除失败: {e}" logging.error(f"[✗] 删除失败 {path}: {e}") return False, msg def delete_registry_key(hkey, subkey): try: backup = backup_registry_key(hkey, subkey) if backup: logging.info(f"已备份: {subkey} -> {backup}") winreg.DeleteKey(hkey, subkey) logging.info(f"[✓] 删除注册表: {hkey_name(hkey)}\\{subkey}") return True, "删除成功" except Exception as e: msg = f"删除失败: {e}" logging.error(f"[✗] 删除失败 {subkey}: {e}") return False, msg # ================== GUI 增强版 ================== class CleanerApp: def __init__(self, root): self.root = root self.root.title("360残留清理助手 v1.1") self.root.geometry("950x750") self.root.resizable(False, False) self.file_vars = {} self.reg_vars = {} self.create_widgets() def create_widgets(self): title = tk.Label(self.root, text="360安全卫士残留清理工具", font=("微软雅黑", 16, "bold"), fg="darkblue") title.pack(pady=10) desc = tk.Label(self.root, text="请先扫描,然后勾选要删除的项目,支持全选/取消。", fg="gray") desc.pack() btn_frame = tk.Frame(self.root) btn_frame.pack(pady=10) tk.Button(btn_frame, text="🔍 扫描残留", command=self.scan, width=15, bg="#4CAF50", fg="white").grid(row=0, column=0, padx=5) tk.Button(btn_frame, text="🗑️ 开始清理", command=self.clean, width=15, bg="#f44336", fg="white").grid(row=0, column=1, padx=5) tk.Button(btn_frame, text="📄 查看日志", command=self.view_log, width=15).grid(row=0, column=2, padx=5) ttk.Separator(self.root, orient='horizontal').pack(fill='x', padx=20, pady=10) # 文件区域 file_label = tk.Label(self.root, text="📁 文件与目录残留", font=("微软雅黑", 12, "bold")) file_label.pack(anchor='w', padx=20) file_outer = tk.Frame(self.root, relief="groove", bd=1) file_outer.pack(fill='x', padx=20, pady=5) self.file_frame = tk.Frame(file_outer) self.file_frame.pack(pady=5) file_btn_frame = tk.Frame(file_outer) file_btn_frame.pack(anchor='w', padx=10, pady=5) tk.Button(file_btn_frame, text="✅ 全选", command=lambda: self.select_all(self.file_vars, True), width=10).pack(side='left') tk.Button(file_btn_frame, text="❌ 取消全选", command=lambda: self.select_all(self.file_vars, False), width=10).pack(side='left') # 注册表区域 reg_label = tk.Label(self.root, text="🪟 注册表残留", font=("微软雅黑", 12, "bold")) reg_label.pack(anchor='w', padx=20, pady=(20,0)) reg_outer = tk.Frame(self.root, relief="groove", bd=1) reg_outer.pack(fill='x', padx=20, pady=5) self.reg_frame = tk.Frame(reg_outer) self.reg_frame.pack(pady=5) reg_btn_frame = tk.Frame(reg_outer) reg_btn_frame.pack(anchor='w', padx=10, pady=5) tk.Button(reg_btn_frame, text="✅ 全选", command=lambda: self.select_all(self.reg_vars, True), width=10).pack(side='left') tk.Button(reg_btn_frame, text="❌ 取消全选", command=lambda: self.select_all(self.reg_vars, False), width=10).pack(side='left') self.status = tk.Label(self.root, text="就绪", fg="blue", anchor='w') self.status.pack(side='bottom', fill='x', padx=10, pady=5) def select_all(self, var_dict, select=True): for var in var_dict.values(): if isinstance(var, tuple): # 注册表 var[0].set(select) else: # 文件 var.set(select) self.status.config(text=f"已{'全选' if select else '取消全选'}") def scan(self): for widget in self.file_frame.winfo_children(): widget.destroy() for widget in self.reg_frame.winfo_children(): widget.destroy() self.file_vars.clear() self.reg_vars.clear() # 扫描文件 for i, path in enumerate(DIRECTORIES): if is_path_exists(path): var = tk.BooleanVar() cb = tk.Checkbutton(self.file_frame, text=path, variable=var, font=("Consolas", 9)) cb.grid(row=i, sticky='w', pady=1) self.file_vars[path] = var if not self.file_vars: tk.Label(self.file_frame, text="未发现残留目录", fg="green").grid(row=0, sticky='w') # 扫描注册表 for i, (hkey, subkey, desc) in enumerate(REGISTRY_ITEMS): if is_reg_key_exists(hkey, subkey): var = tk.BooleanVar() frame = tk.Frame(self.reg_frame) frame.grid(row=i, sticky='w', pady=1) tk.Checkbutton(frame, text=f"{hkey_name(hkey)}\\{subkey}", variable=var, font=("Consolas", 9)).pack(anchor='w') tk.Label(frame, text=f"[{desc}]", fg="gray", font=("微软雅黑", 8)).pack(anchor='w', padx=20) self.reg_vars[(hkey, subkey)] = (var, desc) if not self.reg_vars: tk.Label(self.reg_frame, text="未发现残留注册表项", fg="green").pack(anchor='w') self.status.config(text=f"扫描完成,文件残留 {len(self.file_vars)} 项,注册表残留 {len(self.reg_vars)} 项。") def clean(self): if not any(v.get() for v in self.file_vars.values()) and not any(v[0].get() for v in self.reg_vars.values()): if messagebox.askyesno("提示", "没有勾选任何项目,是否扫描查看?"): self.scan() return if not messagebox.askyesno("确认", "即将删除选中的项目,是否继续?\n建议先备份重要数据。"): return success = 0 fail = 0 for path, var in self.file_vars.items(): if var.get(): ok, _ = delete_directory(path) success += ok fail += not ok for (hkey, subkey), (var, desc) in self.reg_vars.items(): if var.get(): ok, _ = delete_registry_key(hkey, subkey) success += ok fail += not ok messagebox.showinfo("完成", f"清理完成!\n成功: {success} 项\n失败: {fail} 项\n日志已保存") self.status.config(text=f"清理完成,成功 {success},失败 {fail}") def view_log(self): log_window = tk.Toplevel(self.root) log_window.title("清理日志") log_window.geometry("800x500") text = scrolledtext.ScrolledText(log_window, font=("Consolas", 9)) text.pack(fill='both', expand=True) if os.path.exists(LOG_FILE): with open(LOG_FILE, 'r', encoding='utf-8') as f: text.insert('1.0', f.read()) else: text.insert('1.0', "日志文件不存在。") # ================== 主程序 ================== if __name__ == "__main__": import ctypes if not ctypes.windll.shell32.IsUserAnAdmin(): messagebox.showerror("权限", "请以管理员身份运行!") exit() root = tk.Tk() app = CleanerApp(root) root.mainloop()
Kimi
# -*- coding: utf-8 -*- # 360SweepPro 增强版(一键扫描+一键清理+备份+驱动重启删) import os, sys, shutil, winreg, tempfile, subprocess, threading, json, time, pathlib from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5.QtGui import * import ctypes from ctypes import wintypes MOVEFILE_DELAY_UNTIL_REBOOT = 4 kernel32 = ctypes.windll.kernel32 kernel32.MoveFileExW.argtypes = [wintypes.LPCWSTR, wintypes.LPCWSTR, wintypes.DWORD] kernel32.MoveFileExW.restype = wintypes.BOOL ICON = 'res/360SweepPro.ico' LOGO = '360SweepPro' VERSION = 'v1.0' # ---------- 工具 ---------- def log(msg): with open('360SweepPro.log', 'a', encoding='utf-8') as f: f.write(f'{time.strftime("%Y-%m-%d %H:%M:%S")} {msg}\n') def backup_reg(keyPath): """导出一个 .reg 备份""" fname = pathlib.Path(tempfile.gettempdir()) / f'360SweepPro_backup_{int(time.time())}.reg' subprocess.run(['reg', 'export', keyPath, str(fname), '/y'], check=False) return str(fname) def del_reg(keyPath): try: winreg.DeleteKey(winreg.HKEY_CLASSES_ROOT, keyPath[len('HKEY_CLASSES_ROOT\\'):]) return True except: return False def del_file(path): try: if os.path.isdir(path): shutil.rmtree(path) else: os.remove(path) return True except PermissionError: # 驱动被占用 → 注册重启删除 ok = kernel32.MoveFileExW(path, None, MOVEFILE_DELAY_UNTIL_REBOOT) return bool(ok) except: return False # ---------- 扫描线程 ---------- class Scanner(QThread): found = pyqtSignal(str, str) # path, type done = pyqtSignal() def run(self): # 1. 目录 dirs = [os.path.expandvars(p) for p in [ r'%ProgramData%\360safe', r'%ProgramData%\360SD', r'C:\360SANDBOX', r'C:\$360Section', r'%USERPROFILE%\AppData\Roaming\360Safe', r'%USERPROFILE%\AppData\Roaming\360DesktopLite', r'%USERPROFILE%\AppData\Roaming\360Login', r'%USERPROFILE%\AppData\Roaming\360Quarant', r'%USERPROFILE%\AppData\LocalLow\360WD' ]] for d in dirs: if os.path.exists(d): self.found.emit(d, '目录') # 2. 驱动 for drv in pathlib.Path(r'C:\Windows\System32\drivers').glob('360*.sys'): self.found.emit(str(drv), '驱动') # 3. 注册表(递归 GUID) self.scan_reg() self.done.emit() def scan_reg(self): roots = [ (winreg.HKEY_CLASSES_ROOT, r'CLSID'), (winreg.HKEY_CLASSES_ROOT, r'*\shellex\ContextMenuHandlers\Safe360Ext'), (winreg.HKEY_CURRENT_USER, r'Software\360safe'), (winreg.HKEY_CURRENT_USER, r'Software\360se6'), (winreg.HKEY_USERS, r'360SandBox'), (winreg.HKEY_USERS, r'360SPDM') ] for root, sub in roots: try: key = winreg.OpenKey(root, sub) winreg.CloseKey(key) path = 'HKEY_CLASSES_ROOT\\' + sub if root == winreg.HKEY_CLASSES_ROOT else \ 'HKEY_CURRENT_USER\\' + sub if root == winreg.HKEY_CURRENT_USER else \ 'HKEY_USERS\\' + sub self.found.emit(path, '注册表') except: pass # ---------- 主界面 ---------- class MainWin(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle(f'{LOGO} {VERSION}') self.setFixedSize(800, 600) self.setWindowIcon(QIcon(ICON)) self._initUI() self.scanner = Scanner(self) self.scanner.found.connect(self.add_row) self.scanner.done.connect(self.scan_done) self.data = [] # [(path, type, chk), ...] def _initUI(self): central = QWidget() self.setCentralWidget(central) v = QVBoxLayout(central) self.bar = QProgressBar() self.bar.setRange(0, 0) self.bar.hide() v.addWidget(self.bar) self.table = QTableWidget(0, 4) self.table.setHorizontalHeaderLabels(['', '路径', '类型', '结果']) self.table.horizontalHeader().setSectionResizeMode(1, QHeaderView.Stretch) self.table.setSelectionBehavior(QAbstractItemView.SelectRows) h = QHBoxLayout() self.oneScan = QPushButton('一键扫描') self.oneClean= QPushButton('一键清理') self.quitBtn = QPushButton('退出') h.addWidget(self.oneScan) h.addWidget(self.oneClean) h.addWidget(self.quitBtn) self.oneClean.setEnabled(False) v.addWidget(self.table) v.addLayout(h) self.oneScan.clicked.connect(self.start_scan) self.oneClean.clicked.connect(self.one_key_clean) self.quitBtn.clicked.connect(self.close) def start_scan(self): self.data.clear() self.table.setRowCount(0) self.bar.show() self.oneScan.setEnabled(False) self.scanner.start() def add_row(self, path, typ): row = self.table.rowCount() self.table.insertRow(row) chk = QTableWidgetItem() chk.setCheckState(Qt.Checked) self.table.setItem(row, 0, chk) self.table.setItem(row, 1, QTableWidgetItem(path)) self.table.setItem(row, 2, QTableWidgetItem(typ)) self.table.setItem(row, 3, QTableWidgetItem('')) self.data.append((path, typ, chk)) def scan_done(self): self.bar.hide() self.oneScan.setEnabled(True) self.oneClean.setEnabled(True) QMessageBox.information(self, '提示', f'扫描完成,共 {len(self.data)} 条残留') def one_key_clean(self): sel = [(p, t) for p, t, chk in self.data if chk.checkState() == Qt.Checked] if not sel: QMessageBox.information(self, '提示', '请先勾选要清理的项') return ans = QMessageBox.question(self, '确认', f'将清理 {len(sel)} 条记录,并自动备份注册表,继续?') if ans != QMessageBox.Yes: return ok_cnt = 0 for path, typ in sel: bak = '' if typ == '注册表': bak = backup_reg(path) ok = del_reg(path) else: ok = del_file(path) ok_cnt += ok # 回写结果 for row in range(self.table.rowCount()): if self.table.item(row, 1).text() == path: self.table.setItem(row, 3, QTableWidgetItem('已删除' if ok else '失败')) log(f'一键清理完成 成功={ok_cnt} 总数={len(sel)}') QMessageBox.information(self, '完成', f'清理完毕!成功 {ok_cnt}/{len(sel)}\n注册表备份保存在 temp 目录') if __name__ == '__main__': app = QApplication(sys.argv) w = MainWin() w.show() sys.exit(app.exec_())
打包成exe可执行程序的命令,运行需要右键 “以管理员身份运行”
pyinstaller --onefile --windowed 360_cleaner.py
sicnature ---------------------------------------------------------------------
I P 地 址: 216.73.216.187
区 域 位 置: 美国加利福尼亚洛杉矶
系 统 信 息:

Original content, please indicate the source:
同福客栈论坛 | 蟒蛇科普 | 海南乡情论坛 | JiaYu Blog
sicnature ---------------------------------------------------------------------
Welcome to reprint. Please indicate the source https://myzhenai.com/post/4810.html
没有评论