Windows下编译带DLL的C++程序出现「无法在你的电脑上运行」错误
问题:Windows 11下用MSVC CL编译DLL关联EXE后运行提示「This app can't run on your PC」及「Access is denied」
环境信息
- 系统:Windows 11
- 编译器:Microsoft cl 19.37.32825(x64)
- 项目结构:包含
main.cpp和一个需编译为DLL的类 - 对比情况:Ubuntu下静态/动态库均能正常编译运行,Windows下仅静态库正常
问题现象
编译DLL并生成关联EXE后,运行EXE时弹出「This app can't run on your PC」弹窗,控制台同时输出「Access is denied」。
已尝试的无效解决方案
- 通过PowerShell加载不同架构参数的
vcvarsall.bat,确保编译架构一致 - 完全关闭Avast杀毒软件并将项目根目录加入白名单,检查隔离区无异常文件
- 以管理员权限运行PowerShell
- 直接运行EXE、启用Windows 8兼容模式及使用兼容性疑难解答
- 进入安全模式(命令行)运行EXE,仍显示「Access is denied」
- 检查Windows事件查看器,未发现相关异常条目
- 启用Windows开发者模式
复现资源
提供完整项目结构、代码及编译脚本compileAndRun.bat(注:平时使用CMake,本次需手动通过PowerShell命令完成编译)
解决方案
1. 确保DLL导出符号正确
MSVC编译DLL时必须显式导出类/函数,否则EXE无法定位符号导致加载失败。需在代码中区分编译DLL和EXE时的导入导出宏:
// myclass.h #ifdef MYDLL_EXPORTS #define MYDLL_API __declspec(dllexport) #else #define MYDLL_API __declspec(dllimport) #endif class MYDLL_API MyClass { public: void sayHello(); };
编译DLL时需定义MYDLL_EXPORTS宏:
cl /c /DMYDLL_EXPORTS myclass.cpp link /DLL /OUT:myclass.dll myclass.obj
2. 统一编译参数的一致性
保证EXE和DLL的编译参数完全匹配:
- 确认
vcvarsall.bat x64已正确加载,通过cl /help查看当前目标架构是否为x64 - 统一运行时库:比如都使用
/MD(多线程DLL)或/MT(多线程静态),禁止混合使用
编译EXE示例:cl /c /MD main.cpp link /OUT:main.exe main.obj myclass.lib
3. 检查PE文件完整性
用dumpbin工具验证生成的EXE和DLL是否为有效x64 PE文件:
dumpbin /headers main.exe dumpbin /headers myclass.dll
若输出显示架构不匹配或文件损坏,清理项目文件后重新编译。
4. 确认DLL加载路径
EXE运行时需能找到DLL,可通过以下方式确保路径正确:
- 将DLL放在EXE同一目录下
- 把DLL所在目录添加到系统
PATH环境变量 - 编译EXE时用
/LIBPATH:指定DLL的lib文件路径
5. 规避系统权限限制
- 把项目目录从系统保护路径(如
C:\Windows、C:\Program Files)移到普通用户目录(如C:\Users\你的用户名\Projects)重新编译 - 检查文件是否被标记为「来自互联网」:右键EXE/DLL → 属性 → 勾选「解除锁定」(若有该选项)
6. 用工具排查加载细节
- Dependency Walker:打开EXE,查看是否存在缺失的依赖项(如MSVC运行时库)
- Process Monitor:过滤EXE的文件操作,查看加载DLL时是否出现权限拒绝或文件未找到的记录
内容的提问来源于stack exchange,提问作者tom
相关产品推荐
相关产品推荐

