ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

VSCode+MSVC+EasyX环境配置:从编译器选择到图形编程跑通

2026/9/17 18:13:49 拓冰建站 浏览量
VSCode+MSVC+EasyX环境配置:从编译器选择到图形编程跑通 如果你第一次在 VSCode 里写完#include graphics.h按下运行迎接你的却是一大片红色波浪线和fatal error C1083: 无法打开包括文件那多半和我一开始一样选错了编译器。很多人把 VSCode 配好 C/C 环境之后第一反应是去装 MinGW-w64 或者 MSYS2这些跑命令行程序都没有问题但一旦碰到 EASYX就直接卡死。原因其实不复杂EasyX 官方只支持 MSVC也就是微软的 Visual C 编译器它跟 VSCode 本身没有关系VSCode 只是一个壳。这篇文章会从编译器选择讲起一直讲到环境配置、编译任务封装、代码提示消除再到完整实例和报错排查把 VSCode MSVC EasyX 这条路彻底走通。1. 为什么非要用 MSVCEasyX 与编译器的绑定关系1.1 EasyX 不是普通头文件库很多人误以为 EasyX 就是把graphics.h这个头文件拿过来然后随便什么编译器都能用。实际上 EasyX 是一个带静态库的图形库它的实现深度依赖 Windows 的 GDI/GDI 接口而且内部使用了 MSVC 特有的#pragma comment(lib, ...)自动链接机制。也就是说#include graphics.h后编译器会从某个.lib文件里找函数实现再配合 GDI 系列的 Windows 系统库完成图形绘制。这就带来一个现实问题.lib静态库的格式是微软 COFF 格式MinGW 下的 GNU 链接器虽然部分兼容 COFF但并不是所有 MSVC 生成的库都能被正常解析。更重要的是EasyX 官方从设计上只针对 Visual C 做测试和适配社区里流传的 MinGW 可用版本大多是第三方魔改有些人能跑通有些人会遇到各种奇怪的内存错误、链接错误而且没有任何官方技术支持。1.2 MinGW 方案为什么走不通我在知乎、CSDN 上看到很多帖子说“用 MinGW 也可以编译 EasyX”点进去一看要么是旧版 EasyX 的漏网之鱼要么是贴了第三方修改过的库文件。我自己试过一次安装 EasyX 后手动把 lib 文件路径加进 MinGW 链接器编译阶段没问题一运行就崩溃。后来查了 EasyX 官方 FAQ里面写得很明确目前只支持 VC 编译器不支持 GCC/MinGW。如果你只是用 VSCode 写控制台程序MinGW 完全没问题它轻量、好装、和 C/C 扩展配合也顺滑。但要做 EasyX 图形程序就必须在 VSCode 里切换到 MSVC。这个思路想清楚之后后面的事情就顺了VSCode 负责编辑代码MSVC 负责编译链接EasyX 负责提供图形 API三者各干各的完全不冲突。1.3 用 VSCode MSVC 的组合好在哪Visual Studio 全功能 IDE 确实省心打开就能跑。但它的安装体积动辄几十个 GB启动也慢。很多老师、博主推荐的纯 VSCode MSVC 组合本质上就是用 Visual Studio Build Tools 里抽出来的cl.exe编译器配合 VSCode 做文本编辑。这样既能用上官方原版 MSVC 编译器又能保留 VSCode 的轻量和多文件管理体验对写一些小型的 EasyX 课程设计、期末大作业来说非常合适。当然也要接受它的代价环境变量、任务配置、IntelliSense 路径这些都得手动折腾一遍。这篇文章就是为了把这个折腾过程给你压缩到最短。2. 环境准备四件事Build Tools、EasyX、扩展和一次烟雾测试2.1 安装 Visual Studio Build Tools 时最容易犯的错去 visualstudio.microsoft.com 下载 Build Tools这个你不会找错。安装时最关键的一步是勾选“使用 C 的桌面开发”工作负载它会自动带上 MSVC 编译器、Windows SDK、C CMake 工具等一大堆必要组件。我见过不少人大意只装了“通用 Windows 平台开发”或者只装了 .NET结果运行cl提示找不到命令。如果你已经装完但不确定缺什么可以打开 Visual Studio Installer点击 Build Tools 的“修改”确认“使用 C 的桌面开发”这个勾是不是亮的。另一个容易忽略的是 Windows SDKEasyX 底层要调用windows.h如果 SDK 没装全后面编译会报一堆cannot open include file: windows.h。装完之后建议先到开始菜单里找一下“x64 Native Tools Command Prompt for VS 2022”。这是一个已经配置好 MSVC 环境变量的命令行窗口打开后直接输入cl如果能打印出编译器版本信息说明你的 MSVC 编译器已经就绪。如果开始菜单里找不到这个快捷方式大概率是组件没装完整回到 Installer 再检查一遍。2.2 安装 EasyX检测不到 VS 时怎么办从 easyx.cn 官方下载 EasyX 安装包运行后它一般会列出检测到的 VS 版本。你安装 Build Tools 之后正常情况下它会识别出对应的 VC 版本。勾选它点安装安装器会把graphics.h复制到 VC 的 include 目录把对应的.lib文件复制到 lib 目录。但这里有一个非常常见的坑如果你先装了旧版 VS或者 Build Tools 装在非默认路径注册表信息缺失EasyX 可能提示“未检测到 Visual Studio”。解决方式不是干着急而是直接在网上找 EasyX 的压缩包版解压出来你会得到Include和Lib两个文件夹。这样后面就需要你自己把路径告诉编译器这也是这篇文章后面重点要处理的事情。我个人的习惯是不管 EasyX 有没有自动装进 VS都额外留一份解压包。因为 VSCode 的智能提示经常需要手动指定头文件目录有现成的Include/graphics.h路径配置起来会方便很多。2.3 让 VSCode 认识 cl.exevcvarsall.bat 是什么cl.exe和 GCC 有一个非常大的区别它不能直接裸跑必须先加载一堆环境变量告诉它 VC 头文件在哪、Windows SDK 头文件在哪、库文件在哪。这些环境变量通常由vcvarsall.bat脚本统一设置。路径一般是C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Auxiliary\Build\vcvarsall.bat如果你是 VS Community路径会是这样C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvarsall.bat版本不同、安装位置不同路径就不同千万别照抄。一个最笨但最可靠的办法是打开 Windows 搜索直接搜vcvarsall.bat。这个文件非常重要后面不管是手动编译还是配置 VSCode 任务都绕不开它。使用时在 cmd 里敲call C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Auxiliary\Build\vcvarsall.bat x64参数x64表示让编译器生成 64 位程序。如果不确定自己要 x86 还是 x64我建议一律用 x64因为现在大多数系统是 64 位EasyX 也提供了 x64 版本的库文件。2.4 先在终端里跑通一个最简图形程序在做任何 VSCode 配置之前先手写测试一个小程序。新建一个文件夹里面放test.cpp#include graphics.h #include conio.h int main() { initgraph(640, 480); setbkcolor(WHITE); cleardevice(); setfillcolor(RED); fillcircle(320, 240, 100); getch(); closegraph(); return 0; }然后打开“x64 Native Tools Command Prompt for VS 2022”切换到代码所在目录执行cl /EHsc test.cpp /link /SUBSYSTEM:CONSOLE user32.lib gdi32.lib if exist test.exe test.exe如果这个命令直接在命令行里跑通了屏幕上出现一个 640x480 的白底窗口和红色圆形说明编译器、EasyX、系统库三个环节全部正常。这一步极其必要因为后面所有 VSCode 配置只是把这条命令行自动化你连最核心的命令都跑不通在 VSCode 里只会得到更多迷惑报错。3. 把编译过程封装进 VSCodetasks.json 还是 build.bat3.1 为什么嵌套引号会让人崩溃很多人喜欢直接在tasks.json里写编译命令但 MSVC 编译命令本来就很长涉及到带空格的路径、连接符、/link之后的链接参数。如果你把这些全塞进 JSON 的args里引号嵌套会让你怀疑人生。我自己曾经在tasks.json里转义了三层双引号最后直接报call 不是内部或外部命令。所以我的建议是尽量不要把复杂编译命令写进tasks.json而是写一个build.bat批处理文件让 VSCode 只负责调用这个批处理文件。这样既清晰又方便你手动调试。3.2 build.bat 方案推荐在项目目录下新建build.batecho off cd /d %~dp0 call C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Auxiliary\Build\vcvarsall.bat x64 cl /nologo /EHsc /utf-8 main.cpp /link /SUBSYSTEM:CONSOLE /LIBPATH:C:\EasyX\Lib\Win10_x64 user32.lib gdi32.lib if exist main.exe main.exe这里的cd /d %~dp0是把当前目录切到批处理文件所在目录避免你从其他目录触发 build 时找不到main.cpp。/LIBPATH指向 EasyX 库文件所在目录这里写成C:\EasyX\Lib\Win10_x64只是示例实际目录要以你 EasyX 解压位置为准。如果你让 EasyX 自动装进了 VS理论上可以不写这个/LIBPATH但写了也无妨链接器多搜一个路径而已。然后新建.vscode/tasks.json{ version: 2.0.0, tasks: [ { label: build and run EasyX, type: shell, command: build.bat, args: [], problemMatcher: [$msCompile], group: { kind: build, isDefault: true } } ] }接着在main.cpp里写好代码按CtrlShiftBVSCode 就会执行build.bat编译并运行。这个方案最大的好处是之后你想加链接参数、换源文件、调编译选项只需要改build.bat完全不用碰 JSON。3.3 tasks.json 直连方案备选有些人不喜欢多一个批处理文件那也可以把命令直接写进tasks.json。注意下面这段 JSON 的转义反斜杠要写成双反斜杠字符串里的引号要用\{ version: 2.0.0, tasks: [ { label: build and run EasyX direct, type: shell, command: cmd, args: [ /c, call \C:\\Program Files (x86)\\Microsoft Visual Studio\\2022\\BuildTools\\VC\\Auxiliary\\Build\\vcvarsall.bat\ x64 cl /nologo /EHsc /utf-8 main.cpp /link /SUBSYSTEM:CONSOLE /LIBPATH:\C:\\EasyX\\Lib\\Win10_x64\ user32.lib gdi32.lib main.exe ], problemMatcher: [$msCompile], group: { kind: build, isDefault: true } } ] }这个方案暴露出来的可读性问题很明显只要有一个路径写错排查起来非常痛苦。所以日常我还是建议用build.battasks.json直连只适合你临时跑一两个测试文件不想单独建脚本的情况。3.4 参数拆解/EHsc、/utf-8、/SUBSYSTEM、/LIBPATH 到底在干什么我一直觉得抄配置不能光抄得知道每个参数是干嘛的不然报错时根本无从下手。下面这几个参数是 EasyX 编译命令里的核心必须搞清楚。/EHsc是启用 C 异常处理。EasyX 入门代码一般用不上异常但 C 标准库有些地方需要异常支持加上它基本是 MSVC 编译 C 的标配不写可能遇到C4530警告或某些库行为异常。/utf-8表示让编译器把源码文件当作 UTF-8 读取。现在 VSCode 默认文件编码就是 UTF-8但 Windows 在非 UTF-8 地区下的命令行工具默认代码页可能是 GBK不加这个参数源码里的中文注释和outtextxy输出的中文字符串很容易乱码。/link后面的参数全部交给链接器。它的下一级参数包括参数作用/SUBSYSTEM:CONSOLE生成控制台子系统程序运行时带一个黑色命令窗口/SUBSYSTEM:WINDOWS生成 Windows 窗口程序没有控制台黑框/ENTRY:mainCRTStartup把程序入口指定为mainCRTStartup这样即使窗口子系统也能用main函数作为入口/LIBPATH:...给链接器增加一个库文件搜索目录user32.lib gdi32.libEasyX 依赖的两个 Windows 系统库分别提供窗口管理和 GDI 绘图接口如果不想看到黑框把/SUBSYSTEM:CONSOLE换成/SUBSYSTEM:WINDOWS同时加上/ENTRY:mainCRTStartup。这样既保留了用main()写代码的习惯又不会有控制台窗口。这个技巧在课程设计展示的时候特别有用。4. IntelliSense 不报错了c_cpp_properties.json 补全4.1 IntelliSense 和编译不是一回事很多新手在tasks.json里把编译命令配通了程序也能跑但 VSCode 里依然满屏红色波浪线graphics.h下面还有个黄色灯泡提示找不到。这里要搞清楚一个概念编译任务归tasks.json管而编辑器里的代码提示和错误检测归 C/C 扩展管它读的是c_cpp_properties.json。也就是说编译能通过不代表 IntelliSense 认识这个头文件。C/C 扩展默认只搜索官方的系统头文件不会自动感知你命令行了/LIBPATH所以你必须手动告诉它EasyX 的头文件在哪个目录MSVC 的头文件在哪些目录。4.2 includePath 和 compilerPath 的完整写法按CtrlShiftP输入C/C: Edit Configurations (JSON)打开后会生成一个类似下面的配置{ configurations: [ { name: Win64, includePath: [ ${workspaceFolder}/**, C:\\Program Files (x86)\\Microsoft Visual Studio\\2022\\BuildTools\\VC\\Tools\\MSVC\\14.44.35207\\include, C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.26100.0\\ucrt, C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.26100.0\\um, C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.26100.0\\shared, C:\\EasyX\\Include ], defines: [ UNICODE, _UNICODE ], compilerPath: C:\\Program Files (x86)\\Microsoft Visual Studio\\2022\\BuildTools\\VC\\Tools\\MSVC\\14.44.35207\\bin\\Hostx64\\x64\\cl.exe, cStandard: c17, cppStandard: c17, intelliSenseMode: windows-msvc-x64 } ], version: 4 }上面这些带版本号的路径比如14.44.35207和10.0.26100.0每个机器都不一样。手打特别容易错正确做法是打开一个配置好 MSVC 环境的命令行执行echo %INCLUDE% echo %LIB%把输出的每一段路径复制出来对照着填进includePath。一般来说INCLUDE环境变量里列出的就是 C/C 扩展需要搜索的所有头文件目录LIB环境变量里列出的就是链接库目录。compilerPath可以用搜索cl.exe的方式找到也可以用where cl在已配置好的命令行里直接输出。4.3 配置完还有红波浪线的排查姿势就算c_cpp_properties.json配完了你还有可能看到红波浪线。不要慌先看 C/C 扩展的实际诊断信息。按CtrlShiftP输入C/C: Log Diagnostics它会输出当前扩展实际使用的编译器路径、include 路径、预定义宏等关键信息。重点检查输出里的includePath看是否包含 EasyX 的目录以及是否包含 VC 工具链的头文件。另一个常见问题是 IntelliSense 模式和 compilerPath 位数不匹配。比如你compilerPath指向x64\cl.exe但intelliSenseMode设置成了windows-msvc-x86扩展可能就会用 32 位模式解析代码然后对某些 SDK 头文件产生误报。保持windows-msvc-x64和compilerPath的 x64 路径一致很重要。实在不行最简单的验证方式是删除所有配置用 C/C 扩展的命令“Reset IntelliSense Database”或者直接重启 VSCode。这个扩展偶尔会缓存头文件解析结果重启能解决很多诡异问题。5. 完整实测从画圆到小球动画5.1 第一个程序静态绘图加中文输出环境配好之后写一个稍完整一点的例子。把main.cpp改成这样#include graphics.h #include conio.h int main() { initgraph(800, 600); setbkcolor(WHITE); cleardevice(); setlinecolor(RED); setfillcolor(LIGHTRED); fillcircle(400, 250, 120); settextcolor(BLACK); settextstyle(28, 0, 宋体); outtextxy(300, 420, VSCode EasyX); getch(); closegraph(); return 0; }按CtrlShiftB如果build.bat使用/SUBSYSTEM:CONSOLE你会先看到一个黑色控制台窗口和图形窗口同时出现。这个黑框是程序入口决定的不影响图形窗口运行。用键盘随便按一个键程序才会执行getch()之后的closegraph()并退出。outtextxy输出中文经常会遇到乱码。如果你按/utf-8编译源码里的中文“VSCode EasyX”是 UTF-8 编码但 EasyX 绘图用的是系统 GBK 编码这时最好的办法是不要直接写中文而是用 Unicode 字符串再用settextstyle设置中文字体。或者简单点先输出英文测试确认中文问题存在再单独处理。5.2 第二个程序无闪烁小球动画EasyX 写动画的经典坑是闪烁。如果直接在循环里画一帧清一次屏刷新率稍微高一点眼睛就会明显看到闪。正确做法是使用BeginBatchDraw和EndBatchDraw双缓冲机制先把所有图形画在内存画布上再一次刷新到屏幕。我写了一个简单的小球弹射程序#include graphics.h #include conio.h int main() { initgraph(800, 600); int x 50, y 300; int r 30; int vx 6, vy 4; BeginBatchDraw(); while (!_kbhit()) { cleardevice(); setfillcolor(RGB(60, 120, 255)); solidcircle(x, y, r); x vx; y vy; if (x r || x 800 - r) vx -vx; if (y r || y 600 - r) vy -vy; FlushBatchDraw(); Sleep(16); } EndBatchDraw(); closegraph(); return 0; }Sleep(16)大约对应 60 FPS这个刷新率对 EasyX 这种级别的图形库来说已经足够平滑。_kbhit()来自conio.h作用是检测键盘是否有输入一旦按下任意键循环就结束。这个例子跑通之后你就掌握了 EasyX 动画的基本套路修改坐标、清屏、重绘、双缓冲刷新。后面无论做贪吃蛇还是飞机大战核心逻辑都是这套。5.3 运行与分发动态运行库和静态运行库的选择编译出来的main.exe如果想拷到别的电脑上跑可能会遇到VCRUNTIME140.dll missing这类报错。这是因为cl默认使用/MD动态链接到 C/C 运行库目标机器上必须装了 Visual C Redistributable 才能运行。如果你不想让用户在演示前装运行库可以在build.bat的编译选项里改成/MT让运行库静态链接进 execl /nologo /EHsc /utf-8 /MT main.cpp /link /SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup /LIBPATH:C:\EasyX\Lib\Win10_x64 user32.lib gdi32.lib这样生成的 exe 体积会变大几十 KB 到几百 KB但兼容性显著提升。同时注意区分 32 位和 64 位如果你的 EasyX 库放在Win10_x64目录而build.bat用vcvarsall.bat x64编译那没问题如果要用 32 位就去找 EasyX 里对应的Win10目录同时vcvarsall.bat参数改成x86。混用会让程序在启动时报0xc000007b这个错误后面还会提。6. 常见错误清单与排查链路6.1 编译期错误CL 识别不了、头文件找不到我把实际中遇到最多的编译期错误整理成了一张表按报错信息去查会快很多。报错信息根本原因解决思路cl 不是内部或外部命令也不是可运行的程序或批处理文件没有调用vcvarsall.batMSVC 环境变量未加载在 build.bat 或 tasks.json 里先call vcvarsall.batfatal error C1083: 无法打开包括文件: graphics.h: No such file or directoryinclude 路径没包含 EasyX 的头文件目录在 IntelliSense 和编译命令中确认graphics.h所在路径或重装 EasyX 到 VSfatal error C1083: 无法打开包括文件: windows.hWindows SDK 组件缺失安装 Build Tools 时勾选正确的 Windows SDKfatal error C1083: 无法打开包括文件: vcruntime.hVC 工具集没有正确安装或环境变量未设置检查“使用 C 的桌面开发”工作负载是否完整最容易被忽略的一点是即使你写的是 EasyX 程序编译器仍然需要先解析windows.hgraphics.h依赖它。所以头文件搜索顺序的优先级里VC 工具链目录、Windows SDK 目录必须在 EasyX 目录之前不然某些版本会出现graphics.h里引用不到WINGDIAPI之类的诡异错误。把INCLUDE环境变量输出的路径放在includePath的前面能避免这个坑。6.2 链接期错误WinMain 未解析、库文件打不开链接期最常见的报错是unresolved external symbol WinMain referenced in function int __cdecl invoke_main(void)看到WinMain就知道链接器认为你生成了一个窗口程序但没有入口函数WinMain。这通常是因为你在/link里写了/SUBSYSTEM:WINDOWS但源码里用的是main。解决方法是加上/ENTRY:mainCRTStartup或者干脆把/SUBSYSTEM:WINDOWS改成/SUBSYSTEM:CONSOLE。另一个常见错误LINK : fatal error LNK1104: cannot open file EasyXa.lib这是链接器找不到 EasyX 的库文件。原因多半就是/LIBPATH写错了或者 EasyX 没有安装到 MSVC 的库目录。你先在资源管理器里搜索EasyXa.lib或graphics.h找到实际位置后把/LIBPATH改成对应目录。如果目录名有空格一定记得用双引号包住。还有一类错误是unresolved external symbol __imp_...一堆 GDI 函数未解析这说明忘了链接user32.lib gdi32.lib或者这两个库的顺序不对。把这些系统库加在/link后面问题一般就解决了。6.3 运行期错误乱码、黑屏、0xc000007b程序能编译链接但运行阶段出问题往往比编译期更难查。先说乱码。源码里的中文在outtextxy显示成乱码本质是编码不匹配。VSCode 默认 UTF-8 保存文件而旧版 EasyX 在 Windows 默认代码页下绘制字符最简单的方法是用/utf-8编译并在绘制中文前调用正确的字体设置。如果还是乱码就使用宽字符接口比如settextstyle(28, 0, L宋体)配合宽字符字符串。再说黑屏或程序一闪而过。如果你的build.bat用了/SUBSYSTEM:WINDOWS但没有/ENTRY:mainCRTStartup程序可能在初始化窗口之前崩溃。也可以先在main里第一行加上MessageBox(NULL, start, test, MB_OK);这类调试代码确认程序是否真的进入了main。不过 EasyX 最简单的是先退回到/SUBSYSTEM:CONSOLE确认代码本身没问题再考虑要不要消除黑框。最后是启动时报0xc000007b。这个错误基本都是架构不匹配最常见的是用 64 位的cl.exe去链接了 32 位的 EasyX 库文件。确认一下vcvarsall.bat后面的参数、EasyX 库目录里的子目录名、c_cpp_properties.json里的intelliSenseMode三者都是同一个位数。如果你不确定自己项目该用多少位直接全选 x64这已经是目前最省心的选择了。最后再分享两个实际操作中的小技巧。第一配置阶段尽量用“x64 Native Tools Command Prompt for VS”而不是“Developer Command Prompt for VS”因为前者默认就切换到了 64 位环境能少踩一个坑。第二遇到任何路径相关报错不要死盯配置直接用 Everything 搜索vcvarsall.bat、graphics.h、EasyXa.lib的实际位置把你机器上真实存在的路径填进去很多问题立刻就消失了。VSCode 加 MSVC 加 EasyX 这套环境第一次配会觉得麻烦但配通一次之后后面再建新项目基本就是复制粘贴build.bat和两个 JSON 文件的事。