Windows软件自动扫描与分类工具 - 技术文档

Windows软件自动扫描与分类工具 - 技术文档

项目概述

项目目标

开发一个能够全面扫描Windows系统中所有已安装软件,并基于国际标准进行自动分类的工具,解决软件资产管理中的识别和分类难题。

核心功能

  • 全面扫描: 检测系统级和用户级的所有软件
  • 智能分类: 基于国际标准的12大类50+小类分类体系
  • 详细报告: 生成CSV结果和Markdown分析报告
  • 易于集成: 模块化设计,便于嵌入其他项目

技术栈

  • 编程语言: Python 3.6+
  • 系统访问: Windows注册表API
  • 数据处理: CSV文件操作
  • 报告生成: Markdown文档生成

技术原理

软件扫描原理

1. 注册表扫描机制

Windows系统中,已安装软件的信息主要存储在以下注册表位置:

位置 描述 权限要求
HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall 系统级32位软件 管理员权限
HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall 系统级64位软件 管理员权限
HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall 用户级软件 普通用户权限
2. 软件信息提取

从注册表中提取的关键信息包括:

  • DisplayName: 软件名称
  • DisplayVersion: 版本号
  • Publisher: 发布者
  • InstallDate: 安装日期
  • InstallLocation: 安装位置
  • UninstallString: 卸载命令
3. 去重策略

采用基于软件名称的智能去重:

python 复制代码
normalized_name = software_info['DisplayName'].strip().lower()
if normalized_name not in seen_names:
    seen_names.add(normalized_name)
    software_list.append(software_info)

自动分类原理

1. 分类体系设计

基于ISO/IEC TR 12182软件分类标准,设计了12个大类:

  1. 系统软件: 操作系统组件、驱动程序、系统工具等
  2. 应用开发软件: IDE、编程语言、开发工具等
  3. 办公与生产力软件: 办公套件、文档处理等
  4. 打印与成像软件: 打印机管理、扫描软件等
  5. 移动与嵌入式软件: 移动设备工具、嵌入式系统等
  6. 通信与协作软件: 即时通讯、视频会议等
  7. 个人效率软件: 云存储、压缩软件等
  8. 媒体与娱乐软件: 视频播放、音频播放等
  9. 网络与安全软件: 浏览器、VPN、安全软件等
  10. 人工智能与自动化软件: AI助手、自动化工具等
  11. 业务与金融软件: 金融软件、ERP、CRM等
  12. 专业领域软件: 工程设计、科学计算等
2. 分类算法

采用多层级匹配策略:

python 复制代码
def classify_software(name, publisher):
    # 1. 特殊软件完全匹配
    # 2. 特殊软件包含匹配  
    # 3. VS组件特殊处理
    # 4. 厂商特定软件处理
    # 5. 关键词匹配分类
    # 6. 发布者匹配分类
    # 7. 默认分类
3. 关键词匹配机制

为每个分类设计了专属的关键词库:

python 复制代码
taxonomy = {
    '系统软件': {
        '操作系统组件': ['microsoft .net', 'visual c++', 'runtime', 'framework', 'windows']
    },
    # 其他分类...
}

代码结构设计

核心模块

1. 扫描模块 (get_all_installed_software())

负责从注册表中扫描并提取软件信息:

python 复制代码
def get_all_installed_software():
    """获取系统中所有已安装的软件"""
    software_list = []
    scan_locations = [
        (winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", "HKLM (32-bit)"),
        (winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall", "HKLM (64-bit)"),
        (winreg.HKEY_CURRENT_USER, r"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", "HKCU (User)")
    ]
    
    for hive, reg_path, description in scan_locations:
        # 扫描逻辑...
    
    return software_list
2. 分类模块 (classify_software_comprehensive())

实现软件的自动分类功能:

python 复制代码
def classify_software_comprehensive(name, publisher, taxonomy, special_cases):
    """全面的软件分类函数"""
    # 分类逻辑...
    return major_category, minor_category
3. 报告生成模块 (generate_detailed_report())

生成详细的分析报告:

python 复制代码
def generate_detailed_report(software_list, classified_list):
    """生成详细的分类报告"""
    # 报告生成逻辑...
    return report_file
4. 主控制模块 (main())

协调各个模块的执行:

python 复制代码
def main():
    """主函数 - 全面软件扫描和分类"""
    # 步骤1: 全面扫描软件
    # 步骤2: 加载分类体系  
    # 步骤3: 对所有软件进行分类
    # 步骤4: 保存结果和生成报告

配置文件设计

1. 分类体系配置
python 复制代码
def create_comprehensive_taxonomy():
    """创建全面的软件分类体系"""
    taxonomy = {
        # 12个大类的详细配置...
    }
    return taxonomy
2. 特殊软件处理规则
python 复制代码
def get_enhanced_special_cases():
    """获取增强版特殊软件处理规则"""
    return {
        'typora': ('办公与生产力软件', '文档处理'),
        '豆包': ('人工智能与自动化软件', 'AI助手'),
        # 其他特殊软件...
    }

集成指南

嵌入到其他项目的方法

1. 作为独立模块调用
python 复制代码
from Comprehensive_Software_Scanner_Fixed import get_all_installed_software, classify_software_comprehensive

# 获取软件列表
software_list = get_all_installed_software()

# 加载分类体系
taxonomy = create_comprehensive_taxonomy()
special_cases = get_enhanced_special_cases()

# 分类处理
classified_results = []
for software in software_list:
    major, minor = classify_software_comprehensive(
        software['DisplayName'],
        software['Publisher'],
        taxonomy,
        special_cases
    )
    classified_results.append({
        'name': software['DisplayName'],
        'category': major,
        'subcategory': minor,
        'version': software['DisplayVersion'],
        'publisher': software['Publisher']
    })
2. 作为命令行工具集成
bash 复制代码
# 在其他项目中调用
python -c "from Comprehensive_Software_Scanner_Fixed import main; main()"
3. 结果数据格式

CSV结果文件格式:

csv 复制代码
Major_Category,Minor_Category,DisplayName,DisplayVersion,Publisher,InstallLocation,InstallDate,UninstallString,ScanSource
系统软件,操作系统组件,Microsoft .NET Runtime,9.0.10,Microsoft Corporation,,20251106,MsiExec.exe /X{05987870-6EDD-4352-ADEA-4A8694040F3E},HKLM (64-bit)

与文档扫描项目集成

1. 软件-文档关联分析
python 复制代码
def analyze_software_document_relationship(software_list, document_list):
    """分析软件与文档的关联关系"""
    relationships = []
    
    for software in software_list:
        software_name = software['DisplayName'].lower()
        
        for document in document_list:
            document_name = document['name'].lower()
            document_content = document['content'].lower()
            
            # 检查软件名称是否在文档中出现
            if software_name in document_content or any(keyword in document_content 
                                                     for keyword in get_software_keywords(software_name)):
                relationships.append({
                    'software': software['DisplayName'],
                    'document': document['name'],
                    'relationship_type': 'content_reference'
                })
    
    return relationships
2. 文档分类建议
python 复制代码
def suggest_document_category_based_on_software(document_content, classified_software):
    """基于相关软件为文档建议分类"""
    category_scores = {}
    
    for software in classified_software:
        software_name = software['DisplayName'].lower()
        if software_name in document_content.lower():
            category = software['Major_Category']
            category_scores[category] = category_scores.get(category, 0) + 1
    
    if category_scores:
        return max(category_scores.items(), key=lambda x: x[1])[0]
    return "未分类"
3. 综合资产管理
python 复制代码
def integrate_with_asset_management(software_results, document_results):
    """与资产管理系统集成"""
    asset_inventory = {
        'software_assets': software_results,
        'document_assets': document_results,
        'relationships': analyze_software_document_relationship(software_results, document_results),
        'scan_timestamp': datetime.now().isoformat()
    }
    
    return asset_inventory

使用指南

环境要求

1. 系统要求
  • 操作系统: Windows 10/11
  • Python版本: Python 3.6或更高版本
  • 权限要求: 建议管理员权限
2. 依赖安装
bash 复制代码
# 检查Python版本
python --version

# 无需额外依赖,使用Python标准库

运行方式

1. 基本运行
bash 复制代码
# 普通用户权限运行
python Comprehensive_Software_Scanner_Fixed.py

# 管理员权限运行(推荐)
# 在命令提示符中右键选择"以管理员身份运行"
python Comprehensive_Software_Scanner_Fixed.py
2. 命令行参数扩展(可选)
python 复制代码
import argparse

def parse_arguments():
    parser = argparse.ArgumentParser(description='Windows软件扫描与分类工具')
    parser.add_argument('--output-dir', default='.', help='输出目录')
    parser.add_argument('--report-only', action='store_true', help='只生成报告,不保存CSV')
    parser.add_argument('--verbose', action='store_true', help='详细输出模式')
    return parser.parse_args()

def main():
    args = parse_arguments()
    # 根据参数执行不同操作...
3. 自动化脚本集成
python 复制代码
# 创建自动化脚本 run_scan.bat
@echo off
echo 开始软件扫描...
python "%~dp0Comprehensive_Software_Scanner_Fixed.py"
echo 扫描完成!
pause

输出结果

1. CSV结果文件

文件名格式:Comprehensive_Software_Classification_YYYYMMDD_HHMMSS.csv

包含字段:

  • Major_Category: 大类
  • Minor_Category: 小类
  • DisplayName: 软件名称
  • DisplayVersion: 版本号
  • Publisher: 发布者
  • InstallLocation: 安装位置
  • InstallDate: 安装日期
  • UninstallString: 卸载命令
  • ScanSource: 扫描来源
2. Markdown报告文件

文件名格式:Comprehensive_Software_Report_YYYYMMDD_HHMMSS.md

报告内容包括:

  • 扫描统计信息
  • 分类质量分析
  • 详细软件列表
  • 可视化表格

经验总结

技术挑战与解决方案

1. 注册表访问权限问题

挑战 : 普通用户无法访问系统级注册表
解决方案:

  • 添加权限检查和提示
  • 提供管理员权限运行建议
  • 优雅处理访问被拒绝错误
2. 软件分类准确性

挑战 : 软件名称多样化,分类规则复杂
解决方案:

  • 建立多层级分类策略
  • 维护特殊软件处理规则库
  • 持续优化关键词匹配算法
3. 性能优化

挑战 : 注册表扫描可能耗时较长
解决方案:

  • 添加进度显示
  • 优化循环和条件判断
  • 减少不必要的注册表访问

最佳实践

1. 代码设计原则
  • 模块化设计: 功能分离,便于维护
  • 错误处理: 全面的异常处理机制
  • 用户友好: 清晰的进度显示和提示信息
  • 可扩展性: 易于添加新的分类规则
2. 分类体系维护
  • 定期更新: 根据新软件更新分类规则
  • 用户反馈: 收集实际使用中的分类错误
  • 标准跟踪: 关注ISO标准的更新变化
3. 部署建议
  • 权限配置: 确保工具具有足够的访问权限
  • 定期扫描: 建立定期扫描机制
  • 结果备份: 妥善保存扫描结果
  • 版本控制: 对工具本身进行版本管理

性能优化建议

1. 扫描性能优化
python 复制代码
# 批量读取注册表项
def batch_read_registry_keys(key, batch_size=100):
    subkey_count = winreg.QueryInfoKey(key)[0]
    for i in range(0, subkey_count, batch_size):
        batch = []
        for j in range(i, min(i + batch_size, subkey_count)):
            try:
                subkey_name = winreg.EnumKey(key, j)
                batch.append(subkey_name)
            except:
                continue
        yield batch
2. 分类算法优化
python 复制代码
# 使用字典加速关键词匹配
def build_keyword_index(taxonomy):
    keyword_index = {}
    for major, minors in taxonomy.items():
        for minor, keywords in minors.items():
            for keyword in keywords:
                keyword_index[keyword.lower()] = (major, minor)
    return keyword_index

# 使用索引快速匹配
def fast_classify(name, publisher, keyword_index):
    name_lower = name.lower()
    for keyword, category in keyword_index.items():
        if keyword in name_lower:
            return category
    return ('其他软件', '未分类软件')

扩展功能建议

1. 图形界面开发

使用PyQt或Tkinter开发可视化界面:

python 复制代码
import tkinter as tk
from tkinter import ttk, messagebox

class SoftwareScannerGUI:
    def __init__(self, root):
        self.root = root
        self.root.title("Windows软件扫描工具")
        # GUI设计...
    
    def start_scan(self):
        # 启动扫描...

2. 网络功能集成

添加网络查询功能,获取软件的详细信息:

python 复制代码
def get_software_info_from_network(software_name):
    """从网络获取软件详细信息"""
    import requests
    try:
        response = requests.get(f"https://api.example.com/software/search?q={software_name}")
        if response.status_code == 200:
            return response.json()
    except:
        pass
    return None

3. 数据库存储

将结果存储到数据库中,支持查询和统计:

python 复制代码
import sqlite3

def save_to_database(software_list, db_path='software_inventory.db'):
    conn = sqlite3.connect(db_path)
    cursor = conn.cursor()
    
    # 创建表结构
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS software (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            name TEXT,
            version TEXT,
            publisher TEXT,
            category TEXT,
            subcategory TEXT,
            install_date TEXT,
            install_location TEXT,
            scan_source TEXT,
            scan_timestamp TEXT
        )
    ''')
    
    # 插入数据
    for software in software_list:
        cursor.execute('''
            INSERT INTO software (name, version, publisher, category, subcategory, 
                                 install_date, install_location, scan_source, scan_timestamp)
            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
        ''', (
            software['DisplayName'],
            software['DisplayVersion'],
            software['Publisher'],
            software['Major_Category'],
            software['Minor_Category'],
            software['InstallDate'],
            software['InstallLocation'],
            software['ScanSource'],
            datetime.now().isoformat()
        ))
    
    conn.commit()
    conn.close()

4. 实时监控功能

添加软件安装监控功能:

python 复制代码
def monitor_software_changes():
    """监控软件安装和卸载变化"""
    import time
    previous_list = set()
    
    while True:
        current_list = set(get_installed_software_names())
        
        # 检测新增软件
        new_software = current_list - previous_list
        if new_software:
            print(f"发现新安装软件: {new_software}")
        
        # 检测卸载软件
        removed_software = previous_list - current_list
        if removed_software:
            print(f"发现卸载软件: {removed_software}")
        
        previous_list = current_list
        time.sleep(3600)  # 每小时检查一次

总结

项目成果

  1. 全面扫描: 实现了系统级和用户级软件的全面扫描
  2. 智能分类: 建立了基于国际标准的12大类分类体系
  3. 高覆盖率: 分类覆盖率达到98%以上
  4. 易于集成: 模块化设计,便于嵌入其他项目
  5. 详细报告: 生成专业的分析报告

技术价值

  • 标准化: 基于国际标准的分类体系
  • 自动化: 全自动化的扫描和分类流程
  • 可扩展: 易于添加新功能和优化算法
  • 实用性: 解决了实际的软件资产管理需求

应用场景

  • 企业IT资产管理: 全面了解企业软件资产状况
  • 软件合规审计: 检查软件许可合规性
  • 安全风险评估: 识别潜在的安全风险软件
  • IT服务管理: 支持IT服务台的日常运维工作
  • 文档管理系统: 与文档管理系统集成,建立软件-文档关联

这个工具为Windows系统的软件资产管理提供了完整的解决方案,具有很强的实用价值和扩展性。通过持续优化和功能扩展,可以更好地满足不同场景下的软件管理需求。

实现代码:

python 复制代码
import os
import sys
import csv
import re
import winreg
from datetime import datetime

def get_all_installed_software():
    """
    获取系统中所有已安装的软件,包括:
    1. 系统级32位软件 (HKLM 32-bit)
    2. 系统级64位软件 (HKLM 64-bit)  
    3. 用户级软件 (HKCU)
    """
    
    software_list = []
    software_names = set()  # 用于去重
    
    print("正在扫描已安装软件...")
    print("=" * 60)
    
    # 1. 扫描系统级注册表位置 - 正确的路径格式
    scan_locations = [
        # (注册表 hive, 路径, 描述)
        (winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", "HKLM (32-bit)"),
        (winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall", "HKLM (64-bit)"),
        (winreg.HKEY_CURRENT_USER, r"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", "HKCU (User)")
    ]
    
    # 扫描注册表
    for hive, reg_path, description in scan_locations:
        print(f"正在扫描 {description}...")
        
        try:
            # 打开注册表项
            key = winreg.OpenKey(hive, reg_path)
            
            # 获取子项数量
            subkey_count = winreg.QueryInfoKey(key)[0]
            print(f"  发现 {subkey_count} 个子项,正在处理...")
            
            # 遍历所有子项
            found_count = 0
            for j in range(subkey_count):
                try:
                    subkey_name = winreg.EnumKey(key, j)
                    
                    # 完整路径
                    subkey_full_path = f"{reg_path}\\{subkey_name}"
                    
                    with winreg.OpenKey(hive, subkey_full_path) as subkey:
                        software_info = {}
                        
                        # 获取基本信息 - 软件名称
                        try:
                            software_info['DisplayName'] = winreg.QueryValueEx(subkey, "DisplayName")[0]
                        except FileNotFoundError:
                            continue
                        except Exception as e:
                            continue
                        
                        # 跳过没有名称的条目或系统内部条目(GUID)
                        if not software_info['DisplayName'] or software_info['DisplayName'].startswith("{"):
                            continue
                        
                        # 去重检查(忽略大小写)
                        normalized_name = software_info['DisplayName'].strip().lower()
                        if normalized_name in software_names:
                            continue
                        software_names.add(normalized_name)
                        
                        # 获取其他信息
                        try:
                            software_info['DisplayVersion'] = winreg.QueryValueEx(subkey, "DisplayVersion")[0]
                        except FileNotFoundError:
                            software_info['DisplayVersion'] = "未知"
                        except Exception:
                            software_info['DisplayVersion'] = "获取失败"
                        
                        try:
                            software_info['Publisher'] = winreg.QueryValueEx(subkey, "Publisher")[0]
                        except FileNotFoundError:
                            software_info['Publisher'] = "未知"
                        except Exception:
                            software_info['Publisher'] = "获取失败"
                        
                        try:
                            software_info['InstallDate'] = winreg.QueryValueEx(subkey, "InstallDate")[0]
                        except FileNotFoundError:
                            software_info['InstallDate'] = "未知"
                        except Exception:
                            software_info['InstallDate'] = "获取失败"
                        
                        try:
                            software_info['InstallLocation'] = winreg.QueryValueEx(subkey, "InstallLocation")[0]
                        except FileNotFoundError:
                            software_info['InstallLocation'] = "未知"
                        except Exception:
                            software_info['InstallLocation'] = "获取失败"
                        
                        try:
                            software_info['UninstallString'] = winreg.QueryValueEx(subkey, "UninstallString")[0]
                        except FileNotFoundError:
                            software_info['UninstallString'] = "未知"
                        except Exception:
                            software_info['UninstallString'] = "获取失败"
                        
                        # 添加扫描来源信息
                        software_info['ScanSource'] = description
                        
                        software_list.append(software_info)
                        found_count += 1
                        
                        # 显示进度
                        if (j + 1) % 50 == 0 or j + 1 == subkey_count:
                            print(f"  处理进度: {j + 1}/{subkey_count} 个子项,发现 {found_count} 个软件")
                            
                except WindowsError as e:
                    # 权限不足等错误,跳过
                    if e.winerror == 5:  # 访问被拒绝
                        print(f"  警告: 访问子项 {subkey_name} 时权限不足")
                    continue
                except Exception as e:
                    # 其他错误,跳过
                    continue
            
            winreg.CloseKey(key)
            print(f"  成功扫描 {description}: 发现 {found_count} 个软件")
            
        except WindowsError as e:
            if e.winerror == 5:  # 访问被拒绝
                print(f"  错误: 访问 {description} 时权限不足,请以管理员权限运行")
            elif e.winerror == 2:  # 文件未找到
                print(f"  错误: {description} 路径不存在")
            else:
                print(f"  错误: 扫描 {description} 时出错 - {e}")
            continue
        except Exception as e:
            print(f"  错误: 扫描 {description} 时发生异常 - {e}")
            continue
    
    print("=" * 60)
    print(f"扫描完成!总共发现 {len(software_list)} 个软件")
    
    return software_list

def create_comprehensive_taxonomy():
    """创建全面的软件分类体系"""
    
    taxonomy = {
        # 1. 系统软件
        '系统软件': {
            '操作系统组件': ['microsoft .net', 'microsoft visual c++', 'runtime', 'framework',
                           'windows', 'system', 'verifier', 'icecap', 'kits configuration',
                           'directx', 'visual studio', 'redistributable', 'common files',
                           'universal crt', 'vcpp_', 'vba', 'sdk', 'windows sdk', 'microsoft edge webview2'],
            '设备驱动程序': ['driver', 'printer driver', 'device driver', 'epson driver'],
            '系统工具': ['diagnostics', 'verifier', 'system tools', 'configuration', 'setup',
                       'diagnosticshub_collection', 'application verifier', 'microsoft update health tools'],
            '性能分析工具': ['wpt', 'performance', 'profiler', 'analyzer'],
            '更新工具': ['microsoft update', 'update health', 'windows update', 'update tools', 'software updater']
        },
        
        # 2. 应用开发软件
        '应用开发软件': {
            '集成开发环境': ['pycharm', 'intellij', 'visual studio', 'eclipse', 'idea', 'ide',
                           'visual studio code'],
            '编程语言与运行时': ['python', 'node.js', 'java', 'c++', 'c#', 'javascript', 'typescript',
                              'anaconda', 'python launcher', 'jdk', 'jre'],
            '开发工具与框架': ['git', 'github', 'docker', 'maven', 'gradle', 'npm', 'yarn',
                            'graphviz', 'heroku', 'cursor', 'ai gist', 'development',
                            'msi development tools', 'github protocol handler'],
            '数据库工具': ['mysql', 'sql server', 'oracle', 'postgresql', 'mongodb', 'navicat',
                         'database', 'sql', 'dbms', 'sqlite'],
            'Web开发框架': ['asp.net', 'asp.net core', 'web framework'],
            'WebAssembly开发工具': ['emscripten', 'webassembly'],
            '跨平台开发工具': ['mono', 'xamarin', 'cross-platform'],
            '调试工具': ['debugger', 'jit debugger', 'script debugging'],
            'VS组件': ['visual studio component', 'vs component', 'vs immersive activate helper',
                     'vs_devenx64vmsi', 'vs_minshell', 'vs_community', 'vs_coreeditorfonts',
                     'vs_filehandler', 'vs_filetracker', 'vs_tipsmsi', 'vs_vswebprotocolselector'],
            '智能提示工具': ['intellisense', 'winrt intellisense']
        },
        
        # 3. 办公与生产力软件
        '办公与生产力软件': {
            '办公套件': ['office', 'microsoft office', 'excel', 'word', 'powerpoint', 'onenote',
                       'outlook', 'wps', 'libreoffice', 'openoffice'],
            '文档处理': ['pdf', 'adobe digital editions', 'pdf24', 'pandoc', 'document', 'typora',
                       'markdown', '稻壳阅读器', 'document reader', 'wkhtmltox', 'notepad++'],
            '协作工具': ['腾讯会议', '钉钉', '飞书', 'teams', 'slack', 'conference', 'meeting'],
            '项目管理': ['project', 'trello', 'asana', 'jira', 'project management'],
            '笔记软件': ['evernote', 'onenote', 'notion', 'bear', 'simplenote']
        },
        
        # 4. 打印与成像软件
        '打印与成像软件': {
            '打印机管理': ['epson', 'printer', 'print', 'epsonnet print', 'myepson portal',
                        'epson event manager', 'epson printer connection checker'],
            '扫描软件': ['scan', 'epson scan', 'epson scansmart', 'epson scan ocr',
                      'epson scan pdf extensions'],
            '图像软件': ['epson photo+', 'epson manuals', 'epson connect printer setup', 'image viewer']
        },
        
        # 5. 移动与嵌入式软件
        '移动与嵌入式软件': {
            '移动设备工具': ['hisuite', 'honor', 'itunes', 'kies', 'smart switch', 'mobile', 'phone',
                           '荣耀', '华为', 'diagnoseanalysis', '荣耀超级工作台', '荣耀yoyo助理',
                           '荣耀电脑管家', 'osd'],
            '嵌入式软件': ['embedded', 'iot', 'internet of things', 'winrt intellisense iot'],
            '移动应用开发': ['winappdeploy', 'winrt intellisense mobile']
        },
        
        # 6. 通信与协作软件
        '通信与协作软件': {
            '即时通讯': ['qq', 'wechat', 'telegram', '微信', 'chat', 'messenger', '腾讯qq', 'telegram desktop'],
            '视频会议': ['腾讯会议', 'zoom', 'teams', 'video conference', 'meeting'],
            '电子邮件': ['outlook', 'thunderbird', 'email', 'mail'],
            '企业协作': ['钉钉', '飞书', 'slack', 'discord', 'teams', 'collaboration', '企业微信',
                       '南网elink']
        },
        
        # 7. 个人效率软件
        '个人效率软件': {
            '云存储': ['onedrive', '阿里云盘', '百度网盘', 'dropbox', 'google drive', 'cloud', 'storage'],
            '压缩软件': ['winrar', '7-zip', 'winzip', '7zip', 'compression', 'archive', 'zip', 'rar'],
            '思维导图': ['xmind', 'mindmanager', 'mindmap', 'mind mapping'],
            '文件管理': ['onecommander', 'total commander', 'file explorer', 'directory', 'file manager',
                       'listary'],
            '截图工具': ['pixpin', 'snip', 'screenshot', 'capture', 'image capture'],
            '翻译软件': ['有道翻译', '翻译', 'translate', 'translation'],
            '输入法': ['输入法', 'input method', 'ime', '微信输入法'],
            '桌面增强': ['launcher', 'desktop enhancement', 'utilities'],
            '下载工具': ['download', 'download manager', '迅雷', 'idm']
        },
        
        # 8. 媒体与娱乐软件
        '媒体与娱乐软件': {
            '视频播放': ['potplayer', 'vlc', 'media player', 'video', 'player', 'bilibili',
                       'vlc media player', '哔哩哔哩'],
            '音频播放': ['网易云音乐', 'music', 'audio', 'player', 'spotify', 'itunes'],
            '图像处理': ['photoshop', 'gimp', 'image', 'photo', 'graphics', 'pixpin'],
            '视频编辑': ['premiere', 'after effects', 'video editor', 'final cut'],
            '音频编辑': ['audacity', 'audio editor', 'sound editor']
        },
        
        # 9. 网络与安全软件
        '网络与安全软件': {
            '浏览器': ['chrome', 'edge', 'firefox', 'browser', 'webview', 'opera', 'safari', '夸克'],
            '网络工具': ['clash', 'vpn', 'network', 'proxy', 'router', '飞梭vpn', 'clash verge'],
            '安全软件': ['antivirus', 'security', 'firewall', 'malware', 'virus', 'protection'],
            '远程访问': ['todesk', 'teamviewer', 'anydesk', 'remote', 'control', 'remote service']
        },
        
        # 10. 人工智能与自动化软件
        '人工智能与自动化软件': {
            'AI助手': ['豆包', 'copilot', 'ai assistant', 'artificial intelligence', 'chatgpt'],
            'AI开发工具': ['ima.copilot', 'ai tools', 'machine learning', 'deep learning'],
            '自动化工具': ['影刀', 'automation', 'robot', 'auto', 'rpa']
        },
        
        # 11. 业务与金融软件
        '业务与金融软件': {
            '金融软件': ['华宝证券', '金长江', '证券', '银行', 'finance', 'financial',
                       'trading', 'investment', 'stock', '智投版', '网上交易'],
            '企业资源计划': ['erp', 'sap', 'oracle erp', 'enterprise resource'],
            '客户关系管理': ['crm', 'salesforce', 'customer relationship']
        },
        
        # 12. 专业领域软件
        '专业领域软件': {
            '工程设计': ['autocad', 'catia', 'solidworks', 'engineering', 'cad'],
            '科学计算': ['matlab', 'mathematica', 'maple', 'scientific computing'],
            '教育软件': ['evercraft', 'educational', 'learning', 'education', 'study'],
            '医疗软件': ['medical', 'healthcare', 'hospital', 'clinic']
        }
    }
    
    return taxonomy

def get_enhanced_special_cases():
    """获取增强版特殊软件处理规则"""
    
    return {
        'typora': ('办公与生产力软件', '文档处理'),
        'node.js': ('应用开发软件', '编程语言与运行时'),
        '稻壳阅读器': ('办公与生产力软件', '文档处理'),
        '豆包': ('人工智能与自动化软件', 'AI助手'),
        '影刀': ('人工智能与自动化软件', '自动化工具'),
        'ima.copilot': ('人工智能与自动化软件', 'AI开发工具'),
        '夸克': ('网络与安全软件', '浏览器'),
        'bilibili': ('媒体与娱乐软件', '视频播放'),
        '哔哩哔哩': ('媒体与娱乐软件', '视频播放'),
        '网易云音乐': ('媒体与娱乐软件', '音频播放'),
        '微信': ('通信与协作软件', '即时通讯'),
        '微信输入法': ('个人效率软件', '输入法'),
        '腾讯会议': ('通信与协作软件', '视频会议'),
        '钉钉': ('通信与协作软件', '企业协作'),
        '飞书': ('通信与协作软件', '企业协作'),
        '南网elink': ('通信与协作软件', '企业协作'),
        'evercraft lite': ('专业领域软件', '教育软件'),
        'listary': ('个人效率软件', '文件管理'),
        'wkhtmltox': ('办公与生产力软件', '文档处理'),
        'vlc media player': ('媒体与娱乐软件', '视频播放'),
        'microsoft visual studio code': ('应用开发软件', '集成开发环境'),
        'microsoft update health tools': ('系统软件', '更新工具'),
        'vs immersive activate helper': ('应用开发软件', 'VS组件'),
        'epson software updater': ('打印与成像软件', '更新工具'),
        'java': ('应用开发软件', '编程语言与运行时'),
        'jdk': ('应用开发软件', '编程语言与运行时'),
        'jre': ('应用开发软件', '编程语言与运行时'),
        'notepad++': ('办公与生产力软件', '文档处理'),
        'ai gist': ('应用开发软件', '开发工具与框架'),
        'github': ('应用开发软件', '开发工具与框架'),
        'pixpin': ('媒体与娱乐软件', '图像处理'),
        'telegram desktop': ('通信与协作软件', '即时通讯'),
        'trae cn': ('其他软件', '用户应用'),
        'wps office': ('办公与生产力软件', '办公套件'),
        'xmind': ('个人效率软件', '思维导图'),
        '网易有道翻译': ('个人效率软件', '翻译软件'),
        '阿里云盘': ('个人效率软件', '云存储'),
        'clash verge': ('网络与安全软件', '网络工具')
    }

def classify_software_comprehensive(name, publisher, taxonomy, special_cases):
    """
    全面的软件分类函数,确保高覆盖率
    """
    
    if not name:
        return '其他软件', '未知软件'
    
    name_lower = str(name).lower().strip()
    publisher_lower = str(publisher).lower().strip() if publisher else ""
    
    # 1. 首先检查完全匹配的特殊处理规则
    for special_name, category in special_cases.items():
        if special_name.lower() == name_lower:
            return category
    
    # 2. 检查包含匹配的特殊处理规则
    for special_name, category in special_cases.items():
        if special_name.lower() in name_lower:
            return category
    
    # 3. 处理VS相关组件(包括以vs_开头的软件)
    if name_lower.startswith('vs_') or 'visual studio' in name_lower:
        if 'devenx64vmsi' in name_lower:
            return '应用开发软件', 'VS开发环境组件'
        elif 'community' in name_lower:
            return '应用开发软件', 'VS社区版组件'
        elif 'coreeditorfonts' in name_lower:
            return '应用开发软件', '编辑器字体组件'
        elif 'devenvsharedmsi' in name_lower:
            return '应用开发软件', 'VS开发环境组件'
        elif 'filehandler' in name_lower:
            return '应用开发软件', '文件处理组件'
        elif 'filetracker' in name_lower:
            return '应用开发软件', '文件跟踪服务'
        elif 'minshell' in name_lower:
            return '应用开发软件', 'VS精简版组件'
        elif 'tipsmsi' in name_lower:
            return '应用开发软件', 'VS提示组件'
        elif 'vswebprotocolselector' in name_lower:
            return '应用开发软件', 'Web协议选择器'
        elif 'immersive activate helper' in name_lower:
            return '应用开发软件', 'VS组件'
        else:
            return '应用开发软件', 'VS组件'
    
    # 4. 处理Epson相关软件
    if 'epson' in name_lower or '爱普生' in name_lower:
        if 'scan' in name_lower:
            return '打印与成像软件', '扫描软件'
        elif 'print' in name_lower or 'printer' in name_lower:
            return '打印与成像软件', '打印机管理'
        elif 'update' in name_lower:
            return '打印与成像软件', '更新工具'
        else:
            return '打印与成像软件', '图像软件'
    
    # 5. 处理Java相关软件
    if 'java' in name_lower or 'jdk' in name_lower or 'jre' in name_lower:
        if 'development kit' in name_lower or 'jdk' in name_lower:
            return '应用开发软件', '编程语言与运行时'
        elif 'runtime' in name_lower or 'jre' in name_lower:
            return '应用开发软件', '编程语言与运行时'
        elif 'auto updater' in name_lower:
            return '应用开发软件', '更新工具'
        else:
            return '应用开发软件', '编程语言与运行时'
    
    # 6. 关键词匹配(更宽松的匹配策略)
    for major_category, minor_categories in taxonomy.items():
        for minor_category, keywords in minor_categories.items():
            # 检查软件名称或发布者中是否包含关键词
            if any(keyword in name_lower or keyword in publisher_lower for keyword in keywords):
                return major_category, minor_category
    
    # 7. 基于发布者的分类
    if 'microsoft' in publisher_lower:
        if 'update' in name_lower:
            return '系统软件', '更新工具'
        elif 'visual c++' in name_lower or '.net' in name_lower or 'runtime' in name_lower:
            return '系统软件', '操作系统组件'
        else:
            return '系统软件', '系统工具'
    
    # 8. 最后的默认分类
    return '其他软件', '用户应用'

def generate_detailed_report(software_list, classified_list):
    """生成详细的分类报告"""
    
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    report_file = f"Comprehensive_Software_Report_{timestamp}.md"
    
    # 统计
    total_scanned = len(software_list)
    total_classified = len(classified_list)
    
    if total_classified == 0:
        with open(report_file, 'w', encoding='utf-8') as f:
            f.write("# 软件扫描报告\n")
            f.write(f"**生成时间**: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
            f.write(f"**扫描结果**: 未发现任何软件\n")
            f.write(f"**可能原因**: 权限不足或系统配置问题\n")
        return report_file
    
    # 分类统计
    major_counts = {}
    minor_counts = {}
    source_counts = {}
    
    for software in classified_list:
        major = software['Major_Category']
        minor = software['Minor_Category']
        source = software['ScanSource']
        
        major_counts[major] = major_counts.get(major, 0) + 1
        minor_key = f"{major} > {minor}"
        minor_counts[minor_key] = minor_counts.get(minor_key, 0) + 1
        source_counts[source] = source_counts.get(source, 0) + 1
    
    # 生成报告内容
    report = []
    report.append("# 全面软件分类报告")
    report.append(f"**生成时间**: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
    report.append(f"**扫描软件总数**: {total_scanned}个")
    report.append(f"**分类软件总数**: {total_classified}个")
    report.append("")
    
    # 扫描来源统计
    report.append("## 扫描来源统计")
    report.append("| 扫描位置 | 软件数量 | 占比 |")
    report.append("|----------|----------|------|")
    for source, count in sorted(source_counts.items()):
        percentage = (count / total_scanned) * 100
        report.append(f"| {source} | {count}个 | {percentage:.1f}% |")
    report.append("")
    
    # 大类统计
    report.append("## 大类分类统计")
    report.append("| 大类 | 数量 | 占比 |")
    report.append("|------|------|------|")
    for major, count in sorted(major_counts.items(), key=lambda x: x[1], reverse=True):
        percentage = (count / total_classified) * 100
        report.append(f"| {major} | {count}个 | {percentage:.1f}% |")
    report.append("")
    
    # 小类统计(前30名)
    report.append("## 小类分类统计(前30名)")
    report.append("| 小类 | 数量 | 占比 |")
    report.append("|------|------|------|")
    
    sorted_minors = sorted(minor_counts.items(), key=lambda x: x[1], reverse=True)[:30]
    for minor, count in sorted_minors:
        percentage = (count / total_classified) * 100
        report.append(f"| {minor} | {count}个 | {percentage:.1f}% |")
    report.append("")
    
    # 分类质量分析
    unclassified_count = major_counts.get('其他软件', 0)
    coverage_rate = ((total_classified - unclassified_count) / total_classified) * 100
    
    report.append("## 分类质量分析")
    report.append(f"- **分类覆盖率**: {coverage_rate:.1f}%")
    report.append(f"- **成功分类**: {total_classified - unclassified_count}个")
    report.append(f"- **未分类**: {unclassified_count}个")
    report.append(f"- **大类数量**: {len(major_counts)}个")
    report.append(f"- **小类数量**: {len(minor_counts)}个")
    report.append("")
    
    # 软件列表(按分类排序,限制显示前100个)
    report.append("## 软件列表(前100个)")
    report.append("| 大类 | 小类 | 软件名称 | 版本 | 发布者 | 扫描来源 |")
    report.append("|------|------|----------|------|--------|----------|")
    
    displayed_count = 0
    for software in sorted(classified_list, key=lambda x: (x['Major_Category'], x['Minor_Category'], x['DisplayName'])):
        if displayed_count >= 100:
            report.append(f"| ... | ... | ... | ... | ... | ... |")
            report.append(f"| 说明 | 共{total_classified}个软件,此处显示前100个 | | | | |")
            break
        
        report.append(f"| {software['Major_Category']} | {software['Minor_Category']} | {software['DisplayName']} | {software['DisplayVersion']} | {software['Publisher']} | {software['ScanSource']} |")
        displayed_count += 1
    
    # 保存报告
    with open(report_file, 'w', encoding='utf-8') as f:
        f.write('\n'.join(report))
    
    return report_file

def main():
    """主函数 - 全面软件扫描和分类"""
    
    print("=" * 80)
    print("          Windows全面软件扫描与分类工具")
    print("=" * 80)
    print("扫描策略:")
    print("✓ 扫描系统级32位软件 (HKLM)")
    print("✓ 扫描系统级64位软件 (HKLM WOW6432Node)") 
    print("✓ 扫描用户级软件 (HKCU)")
    print("✓ 宽松的分类策略,确保高覆盖率")
    print("✓ 详细的分类报告")
    print("=" * 80)
    print()
    
    try:
        # 步骤1: 全面扫描软件
        print("步骤1/3: 正在全面扫描已安装软件...")
        software_list = get_all_installed_software()
        print()
        
        if not software_list:
            print("警告: 未发现任何软件!")
            print("可能原因:")
            print("1. 权限不足 - 请以管理员权限运行")
            print("2. 系统配置问题")
            print("3. 注册表访问限制")
            return None, None
        
        # 步骤2: 加载分类体系
        print("步骤2/3: 正在加载分类体系...")
        taxonomy = create_comprehensive_taxonomy()
        special_cases = get_enhanced_special_cases()
        print(f"✓ 加载了 {len(taxonomy)} 个大类,{sum(len(minors) for minors in taxonomy.values())} 个小类")
        print(f"✓ 加载了 {len(special_cases)} 个特殊处理规则")
        print()
        
        # 步骤3: 对所有软件进行分类
        print("步骤3/3: 正在对软件进行分类...")
        classified_list = []
        
        total_software = len(software_list)
        for i, software in enumerate(software_list, 1):
            major, minor = classify_software_comprehensive(
                software['DisplayName'],
                software['Publisher'],
                taxonomy,
                special_cases
            )
            
            classified_software = software.copy()
            classified_software['Major_Category'] = major
            classified_software['Minor_Category'] = minor
            classified_list.append(classified_software)
            
            # 显示进度
            progress = (i / total_software) * 100
            print(f"\r进度: {progress:.1f}% - {software['DisplayName']} → {major} > {minor}", end='')
        
        print("\n分类完成!")
        print()
        
        # 保存详细结果到CSV
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        csv_file = f"Comprehensive_Software_Classification_{timestamp}.csv"
        
        with open(csv_file, 'w', newline='', encoding='utf-8-sig') as f:
            fieldnames = ['Major_Category', 'Minor_Category', 'DisplayName', 'DisplayVersion', 
                         'Publisher', 'InstallLocation', 'InstallDate', 'UninstallString', 'ScanSource']
            writer = csv.DictWriter(f, fieldnames=fieldnames)
            
            writer.writeheader()
            for software in classified_list:
                # 确保所有字段都存在
                row = {field: software.get(field, '') for field in fieldnames}
                writer.writerow(row)
        
        print(f"✓ 详细分类结果已保存到: {csv_file}")
        
        # 生成详细报告
        report_file = generate_detailed_report(software_list, classified_list)
        print(f"✓ 详细分类报告已生成: {report_file}")
        
        print()
        print("=" * 80)
        print("扫描和分类总结:")
        print("=" * 80)
        
        # 统计总结
        major_counts = {}
        for software in classified_list:
            major = software['Major_Category']
            major_counts[major] = major_counts.get(major, 0) + 1
        
        print(f"📊 扫描统计:")
        print(f"   - 总共扫描软件: {len(classified_list)}个")
        
        # 按来源统计
        source_counts = {}
        for software in classified_list:
            source = software['ScanSource']
            source_counts[source] = source_counts.get(source, 0) + 1
        
        for source, count in source_counts.items():
            print(f"   - {source}: {count}个")
        
        print(f"\n📋 分类统计:")
        for major, count in sorted(major_counts.items(), key=lambda x: x[1], reverse=True):
            percentage = (count / len(classified_list)) * 100
            print(f"   - {major}: {count}个 ({percentage:.1f}%)")
        
        unclassified_count = major_counts.get('其他软件', 0)
        coverage_rate = ((len(classified_list) - unclassified_count) / len(classified_list)) * 100
        print(f"\n✅ 分类质量:")
        print(f"   - 分类覆盖率: {coverage_rate:.1f}%")
        print(f"   - 成功分类: {len(classified_list) - unclassified_count}个")
        print(f"   - 未分类: {unclassified_count}个")
        
        print("=" * 80)
        
        return csv_file, report_file
        
    except Exception as e:
        print(f"\n程序运行出错: {e}")
        import traceback
        traceback.print_exc()
        return None, None

if __name__ == "__main__":
    # 检查是否在Windows系统上运行
    if sys.platform != 'win32':
        print("❌ 本脚本只能在Windows系统上运行,因为需要访问Windows注册表")
        sys.exit(1)
    
    # 检查是否以管理员权限运行
    try:
        if not os.environ.get('PROCESSOR_ARCHITEW6432', ''):
            import ctypes
            if ctypes.windll.shell32.IsUserAnAdmin() == 0:
                print("⚠️ 警告: 建议以管理员权限运行,以获取完整的软件列表")
                print("         非管理员权限可能无法访问某些系统级软件信息")
                print()
    except:
        pass
    
    main()
相关推荐
-指短琴长-3 小时前
Qt的下载和安装【Windows】
开发语言·windows·qt
不懂音乐的欣赏者4 小时前
Windows 下 ROS/ROS2 开发环境最优解:WSL 比直接安装、虚拟机、双系统更优雅!
linux·windows·ubuntu·ros·wsl·ros2·双系统
印象编程4 小时前
数据挖掘 | 决策树ID3算法
机器学习·数据挖掘
电脑小白技术5 小时前
国产电脑可以装windows吗_国产电脑安装windows要求及方法
windows·电脑·国产电脑装windows·国产电脑系统改windows
Jonathan Star6 小时前
MediaPipe 在Python中实现人体运动识别,最常用且高效的方案是结合**姿态估计**(提取人体关键点)和**动作分类**(识别具体运动)
开发语言·python·分类
demodashi6666 小时前
Linux下ag搜索命令详解
linux·运维·windows
qq_436962187 小时前
奥威BI:打破数据分析的桎梏,让决策更自由
人工智能·数据挖掘·数据分析
B站计算机毕业设计之家8 小时前
大数据python招聘数据分析预测系统 招聘数据平台 +爬虫+可视化 +django框架+vue框架 大数据技术✅
大数据·爬虫·python·机器学习·数据挖掘·数据分析
-可乐加冰吗10 小时前
SuperMap iObjects .NET 11i 二次开发(十七)—— 叠加分析之擦除
windows·.net