问题简述
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上可能直接运行闪退,不产生任何提示。