使用python写一个应用程序要求实现微软常用vc++功能排查与安装功能

python 复制代码
import os
import sys
import subprocess
import re
import requests
import tempfile
import platform
from bs4 import BeautifulSoup
import winreg

class VCRedistManager:
    def __init__(self):
        self.supported_versions = {
            "2005": {
                "x86": "https://download.microsoft.com/download/8/B/4/8B42259F-5D70-43F4-AC2E-4B208FD8D66A/vcredist_x86.exe",
                "x64": "https://download.microsoft.com/download/8/B/4/8B42259F-5D70-43F4-AC2E-4B208FD8D66A/vcredist_x64.exe"
            },
            "2008": {
                "x86": "https://download.microsoft.com/download/d/2/4/d242c3fb-da5a-4542-ad66-f9661d0a8d19/vcredist_x86.exe",
                "x64": "https://download.microsoft.com/download/d/2/4/d242c3fb-da5a-4542-ad66-f9661d0a8d19/vcredist_x64.exe"
            },
            "2010": {
                "x86": "https://download.microsoft.com/download/1/6/5/165255E7-1014-4D0A-B094-B6A430A6BFFC/vcredist_x86.exe",
                "x64": "https://download.microsoft.com/download/1/6/5/165255E7-1014-4D0A-B094-B6A430A6BFFC/vcredist_x64.exe"
            },
            "2013": {
                "x86": "https://download.microsoft.com/download/2/E/6/2E61CFA4-993B-4DD4-91DA-3737CD5CD6E3/vcredist_x86.exe",
                "x64": "https://download.microsoft.com/download/2/E/6/2E61CFA4-993B-4DD4-91DA-3737CD5CD6E3/vcredist_x64.exe"
            },
            "2015-2022": {
                "x86": "https://aka.ms/vs/17/release/vc_redist.x86.exe",
                "x64": "https://aka.ms/vs/17/release/vc_redist.x64.exe",
                "arm64": "https://aka.ms/vs/17/release/vc_redist.arm64.exe"
            }
        }
        
        # 检查是否在Windows系统上运行
        if platform.system() != "Windows":
            print("错误: 此工具仅适用于Windows系统")
            sys.exit(1)
            
        # 检查是否以管理员权限运行
        self.is_admin = self.check_admin()
        if not self.is_admin:
            print("警告: 建议以管理员权限运行此程序以确保安装功能正常工作")

    def check_admin(self):
        """检查程序是否以管理员权限运行"""
        try:
            return os.getuid() == 0
        except AttributeError:
            import ctypes
            return ctypes.windll.shell32.IsUserAnAdmin() != 0

    def get_installed_versions(self):
        """获取系统中已安装的VC++版本"""
        installed = {}
        
        # 检查注册表中的已安装程序
        reg_paths = [
            r"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall",
            r"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
        ]
        
        for reg_path in reg_paths:
            try:
                key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, reg_path)
                i = 0
                while True:
                    try:
                        subkey_name = winreg.EnumKey(key, i)
                        subkey = winreg.OpenKey(key, subkey_name)
                        
                        # 尝试获取显示名称
                        try:
                            display_name = winreg.QueryValueEx(subkey, "DisplayName")[0]
                            
                            # 检测VC++ redistributable
                            vc_pattern = re.compile(r'Visual C\+\+ \d+ Redistributable(?: \(x86\)|\(x64\)|\(ARM64\))?')
                            if vc_pattern.search(display_name):
                                # 提取版本信息
                                version_match = re.search(r'\d{4}', display_name)
                                arch_match = re.search(r'(x86|x64|ARM64)', display_name)
                                
                                if version_match:
                                    version = version_match.group()
                                    # 特殊处理2015-2022版本
                                    if version == "2015" or version == "2017" or version == "2019" or version == "2022":
                                        version = "2015-2022"
                                        
                                    arch = arch_match.group().lower() if arch_match else "unknown"
                                    
                                    if version not in installed:
                                        installed[version] = set()
                                    installed[version].add(arch)
                        except WindowsError:
                            pass
                            
                        winreg.CloseKey(subkey)
                        i += 1
                    except WindowsError:
                        break
                winreg.CloseKey(key)
            except WindowsError:
                pass
                
        # 转换集合为列表以便于处理
        for version in installed:
            installed[version] = list(installed[version])
            
        return installed

    def display_installed_versions(self, installed_versions):
        """显示已安装的VC++版本"""
        print("\n已安装的Microsoft Visual C++ Redistributable版本:")
        if not installed_versions:
            print("  未检测到已安装的VC++ Redistributable版本")
            return
            
        for version in sorted(installed_versions.keys()):
            arches = ", ".join(installed_versions[version])
            print(f"  {version} - 架构: {arches}")

    def check_missing_versions(self, installed_versions):
        """检查缺失的VC++版本"""
        missing = {}
        
        for version, arches in self.supported_versions.items():
            if version not in installed_versions:
                # 整个版本都缺失
                missing[version] = list(arches.keys())
            else:
                # 检查该版本下缺失的架构
                installed_arches = installed_versions[version]
                for arch in arches.keys():
                    if arch not in installed_arches:
                        if version not in missing:
                            missing[version] = []
                        missing[version].append(arch)
                        
        return missing

    def display_missing_versions(self, missing_versions):
        """显示缺失的VC++版本"""
        print("\n缺失的Microsoft Visual C++ Redistributable版本:")
        if not missing_versions:
            print("  没有检测到缺失的VC++ Redistributable版本")
            return
            
        for version in sorted(missing_versions.keys()):
            arches = ", ".join(missing_versions[version])
            print(f"  {version} - 架构: {arches}")

    def download_and_install(self, version, arch):
        """下载并安装指定版本和架构的VC++ redistributable"""
        if version not in self.supported_versions or arch not in self.supported_versions[version]:
            print(f"错误: 不支持的VC++版本 {version} 或架构 {arch}")
            return False
            
        url = self.supported_versions[version][arch]
        print(f"\n正在下载 {version} {arch} 版本...")
        
        try:
            # 创建临时文件
            with tempfile.NamedTemporaryFile(suffix=".exe", delete=False) as tmp_file:
                response = requests.get(url, stream=True)
                response.raise_for_status()
                
                # 下载文件
                total_size = int(response.headers.get('content-length', 0))
                downloaded_size = 0
                
                for chunk in response.iter_content(chunk_size=8192):
                    if chunk:
                        tmp_file.write(chunk)
                        downloaded_size += len(chunk)
                        progress = (downloaded_size / total_size) * 100 if total_size > 0 else 0
                        print(f"下载进度: {progress:.1f}%", end='\r')
                
                installer_path = tmp_file.name
                print("\n下载完成,准备安装...")
            
            # 运行安装程序
            print(f"正在安装 {version} {arch} 版本...")
            subprocess.run([installer_path, "/quiet", "/norestart"], check=True)
            print(f"{version} {arch} 版本安装完成")
            
            # 清理临时文件
            try:
                os.unlink(installer_path)
            except:
                pass
                
            return True
            
        except Exception as e:
            print(f"安装过程出错: {str(e)}")
            return False

    def install_missing(self, missing_versions, select_all=False):
        """安装缺失的VC++版本"""
        if not missing_versions:
            print("没有需要安装的缺失版本")
            return
            
        for version in sorted(missing_versions.keys()):
            arches = missing_versions[version]
            
            for arch in arches:
                if not select_all:
                    response = input(f"是否安装 {version} {arch} 版本? (y/n): ")
                    if response.lower() not in ['y', 'yes']:
                        continue
                
                self.download_and_install(version, arch)

    def run(self):
        """运行VC++ Redistributable管理工具"""
        print("="*50)
        print("Microsoft Visual C++ Redistributable 管理工具")
        print("="*50)
        
        while True:
            print("\n请选择操作:")
            print("1. 检查已安装的VC++版本")
            print("2. 检查并安装缺失的VC++版本")
            print("3. 安装所有支持的VC++版本")
            print("4. 退出")
            
            choice = input("请输入选项 (1-4): ")
            
            if choice == '1':
                installed = self.get_installed_versions()
                self.display_installed_versions(installed)
                
            elif choice == '2':
                installed = self.get_installed_versions()
                self.display_installed_versions(installed)
                
                missing = self.check_missing_versions(installed)
                self.display_missing_versions(missing)
                
                if missing:
                    self.install_missing(missing)
                    
            elif choice == '3':
                confirm = input("确定要安装所有支持的VC++版本吗? 这可能需要一些时间和磁盘空间。(y/n): ")
                if confirm.lower() in ['y', 'yes']:
                    # 创建一个包含所有版本和架构的"缺失"字典
                    all_versions = {v: list(a.keys()) for v, a in self.supported_versions.items()}
                    self.install_missing(all_versions, select_all=True)
                    
            elif choice == '4':
                print("感谢使用,再见!")
                break
                
            else:
                print("无效的选项,请重试")

if __name__ == "__main__":
    try:
        manager = VCRedistManager()
        manager.run()
    except Exception as e:
        print(f"程序出错: {str(e)}")
        sys.exit(1)
相关推荐
代码充电宝3 小时前
LeetCode 算法题【简单】283. 移动零
java·算法·leetcode·职场和发展
ccccczy_6 小时前
Spring Security 深度解读:JWT 无状态认证与权限控制实现细节
java·spring security·jwt·authentication·authorization·securityfilterchain·onceperrequestfilter
Lin_Aries_04216 小时前
容器化 Tomcat 应用程序
java·linux·运维·docker·容器·tomcat
sheji34166 小时前
【开题答辩全过程】以 springboot高校社团管理系统的设计与实现为例,包含答辩的问题和答案
java·spring boot·后端
zzywxc7877 小时前
大模型落地实践指南:从技术路径到企业级解决方案
java·人工智能·python·microsoft·golang·prompt
相与还7 小时前
IDEA+SpringBoot实现远程DEBUG到本机
java·spring boot·intellij-idea
小杨勇敢飞7 小时前
IDEA 2024 中创建 Maven 项目的详细步骤
java·ide·intellij-idea
野犬寒鸦7 小时前
从零起步学习Redis || 第四章:Cache Aside Pattern(旁路缓存模式)以及优化策略
java·数据库·redis·后端·spring·缓存
白水先森8 小时前
C语言作用域与数组详解
java·数据结构·算法