问题:Visual Studio 2022编译的程序部署在Win10电脑上无法运行

问题简述

Visual Studio 2022编译的32位Debug版本MFC界面程序在Win11本机上运行正常,但部署到目标Win10电脑后运行,报了0xc000007b的错。

解决过程

这个问题多半是缺少vcruntime140d.dll、mfc140d.dll、msvcp140d.dll等库造成的,将它们拷贝进执行路径下,运行后依然报错,猜测可能缺少其它dll依赖。

于是写了个python程序,将vs2022中调试运行时输出日志中显示已加载的dll文件路径提取出来,并将这些dll拷贝到某个文件夹,再部署到目标电脑上。代码如下:

import os
import re
import shutil


def copy_dll_files():
    try:
        # 创建目标目录
        desktop = os.path.join(os.path.expanduser("~"), "Desktop")
        target_dir = os.path.join(desktop, "needdll")
        system_dir = os.path.join(target_dir, "System")
        project_dir = os.path.join(target_dir, "Project")
        program_dir = os.path.join(target_dir, "Program")

        # 创建目录结构
        for dir_path in [system_dir, project_dir, program_dir]:
            os.makedirs(dir_path, exist_ok=True)

        # 读取日志文件并提取DLL路径
        with open('log.txt', 'r', encoding='utf-8') as f:
            content = f.read()
            
        dll_pattern = r'[A-Za-z]:\\[^"\n]+\.dll'
        dll_paths = set(re.findall(dll_pattern, content))
        
        # 用于统计
        copied_count = {'System': 0, 'Project': 0, 'Program': 0}
        failed_copies = []

        # 复制文件
        for dll_path in sorted(dll_paths):
            try:
                if os.path.exists(dll_path):
                    dll_name = os.path.basename(dll_path)
                    
                    # 根据路径决定目标目录
                    if "Windows" in dll_path:
                        target_path = os.path.join(system_dir, dll_name)
                        category = 'System'
                    elif "Program Files" in dll_path:
                        target_path = os.path.join(program_dir, dll_name)
                        category = 'Program'
                    else:
                        target_path = os.path.join(project_dir, dll_name)
                        category = 'Project'

                    # 复制文件
                    shutil.copy2(dll_path, target_path)
                    copied_count[category] += 1
                    print(f"已复制: {dll_path} -> {target_path}")
                else:
                    failed_copies.append(f"文件不存在: {dll_path}")
            except Exception as e:
                failed_copies.append(f"复制失败 {dll_path}: {str(e)}")

        # 打印统计信息
        print("\n复制完成统计:")
        print(f"系统DLL: {copied_count['System']} 个")
        print(f"程序DLL: {copied_count['Program']} 个")
        print(f"项目DLL: {copied_count['Project']} 个")
        print(f"总计: {sum(copied_count.values())} 个")

        # 打印失败信息
        if failed_copies:
            print("\n复制失败的文件:")
            for fail in failed_copies:
                print(fail)

    except Exception as e:
        print(f"程序执行失败: {str(e)}")


if __name__ == "__main__":
    copy_dll_files()

再次运行后,没有弹出报错框,但是程序连界面都没出来就退出了(任务管理器中观察所得)。通过depends.exe查看exe程序的依赖,发现api-ms-win-core-xxx.dll以及api-ms-win-crt-xxx.dll等动态库缺失,但这些库在vs2022调试运行时输出的动态库加载信息里是看不到的。

在电脑上搜索这些文件,能搜索到一大堆,一部分在VIsual Studio软件安装路径下,还有一部分在其它应用程序路径下,同名dll的大小也不尽相同。因此猜测,应用程序部署时需要将这些库一起打包部署,以防目标机器上缺少这些库或者库的版本不对。

观察到部分路径中带有10.0.19041.0字样,这与我项目中使用的Windows sdk版本一致,通过在everything软件中尽心路径匹配及关键词搜索,基本能确定要拷贝的就是C:\Program Files (x86)\Windows Kits\10\Redist\10.0.19041.0\ucrt\DLLs\x86路径下的dll。拷贝至目标机器执行路径后,程序运行正常。

动态库搜索结果

尝试在Win7上部署,用同样的方法也能解决运行依赖问题。但有一点很明显的不同,Win7上更容易弹出缺少某某dll的报错框,而Win10上可能直接运行闪退,不产生任何提示。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值