简介Visual C 2008 SP1 运行库 x86/x64 官方正式版面向缺少 VC 运行环境、启动软件时频繁遇到 dll 丢失提示的用户也适合需要为 32 位与 64 位程序补齐 CRT、标准 C、ATL、MFC、OpenMP 及 MSDIA 等运行时组件的开发与运维人员。C/C 编写的程序通常依赖相应的动态链接库才能正常启动缺少运行库时容易出现报错或无法打开的情况。压缩包共 3 个文件以 2 个 exe 安装程序和 1 个 htm 说明页为主整体约 9.2MB体积轻量便于按系统架构选择对应组件部署。描述中列出的适用系统包括 Windows 2000 SP4、Server 2003、Vista 与 XP覆盖早期常见桌面和服务器环境已有 789 人学习下载。其价值在于让未安装 Visual Studio 2008 的计算机也能运行由 VC 2008 编写的程序减少运行库缺失造成的启动失败在支持并行程序集的操作系统上相关组件会部署到 WinSxS 缓存可作为软件兼容性排查与基础运行环境修复的常用工具。1. 位数选错导致 VC 2008 运行库装不上接手一台新机器我第一件事通常不是装驱动而是补齐运行库。VC 2008 运行库 x86/x64 SP1 是最容易漏掉的一个某开发者的老采集程序双击后弹出 0xc000007b他折腾一下午重装系统也没解决最后发现只是 64 位机器上没装 32 位那份。这类环境在工控上位机、老 ERP 客户端、十年前的图像处理 Demo 里极其常见装不好就只留下一个一闪而过的报错框再加一份看不懂的 SideBySide 事件日志。下面按我实际部署的顺序记录先确认装哪个包再走手动和静默安装然后讲怎么把它放进发布包最后是几处常见故障的解决办法。手里拿到的是官方 SP1 正式版 x86/x64 双包一步步走完基本能跑通。2. 装前清点x86 与 x64 的判断依据是进程位宽很多人拿到压缩包第一反应是看自己系统是 64 位然后只装 x64。这一步就错了。Windows 的加载器按进程找 DLL不是按系统64 位系统上跑一个 32 位 exe它去SysWOW64找msvcr90.dll跑 64 位 exe 才去System32。所以只要是 64 位机器两个包通常都得装——哪怕你主程序是纯 64 位架在它上面的许可证服务、加密壳、老的报表控件随便哪个是 32 位的缺一份就起不来。2.1 先确认系统架构再确认进程架构在命令行里敲三条比在“此电脑属性”里看更靠谱也方便以后写进部署脚本:: PROCESSOR_ARCHITECTURE 在 32 位进程里会显示 x86别被它骗了 echo %PROCESSOR_ARCHITECTURE% :: 这一条只有 64 位系统上的 32 位进程才有值返回 AMD64 就说明系统是 64 位 echo %PROCESSOR_ARCHITEW6432% :: 系统层面的权威答案 wmic os get osarchitecturePROCESSOR_ARCHITECTURE是最容易误判的一个环境变量用 32 位 cmd 打开时它是x86但系统其实是 64 位。判断依据是PROCESSOR_ARCHITEW6432有没有值以及wmic返回的是64 位还是32 位。我一般直接看wmic那一行脚本里则用PROCESSOR_ARCHITEW6432做分支因为它不需要额外调用进程速度快。确认完系统再看程序右键 exe 看属性里有没有“兼容性→以兼容模式运行”之外的线索并不靠谱直接看文件头更干脆。用 PowerShell 读 PE 头0x8664是 64 位0x014c是 32 位# 读 PE 文件头里的 Machine 字段判断 exe/dll 是 32 位还是 64 位 $path D:\app\collector.exe $fs [IO.File]::OpenRead($path) $br New-Object IO.BinaryReader($fs) $fs.Position 0x3C $peOffset $br.ReadInt32() $fs.Position $peOffset 4 $machine $br.ReadUInt16() $br.Close() switch ($machine) { 0x014c { x86 (32 位) } 0x8664 { x64 (64 位) } default { 未知: 0x{0:X} -f $machine } }这段脚本的关键在偏移量先读0x3C处的 4 字节拿到 PE 头偏移再跳过去读Machine字段PE 签名PE\0\0之后 2 字节。批量扫一个目录的 exe 时我会把它包成Get-ChildItem -Recurse -Filter *.exe | ForEach-Object一次把所有依赖位数摸清楚免得装完一半才发现还有个 32 位组件。2.2 SP1 和 RTM 不是一回事版本号决定能不能加载这是我认为最该先讲清楚的一点。VC 2008 的 CRT 走的是 Side-by-Side 私有程序集机制应用程序的 manifest 里写死了要哪个版本的Microsoft.VC90.CRT加载器只认完全匹配的版本除非系统里装了策略重定向。所以你装了运行库不等于装对了版本。版本系列说明常见来源9.0.21022.x2008 原始 RTM 版 CRT最早的 vcredist老光盘里常见9.0.30729.x2008SP1的 CRT本文这套官方 SP1 正式版 x86/x64 包9.0.30729.4148 等后缀SP1 之后的安全更新版同一大版本的不同 build系统更新或新版 redist 带入9.0.30729.6161 等后缀再往后的累积更新 build同上用 SP1 编译出来的程序manifest 要的是9.0.30729.x你机器上只有9.0.21022.x的话照样报“应用程序无法正常启动(0xc0150002)”。反过来只装了 SP1、程序是 RTM 编译的一般能靠同版本共存解决但更稳的做法是两种 build 都留着——Side-by-Side 的设计初衷就是让它们并存不冲突。我吃过一次亏为了“清理”把旧版运行库一口气卸掉结果一个五年没动过的老打印控件直接罢工。2.3 装前查残留三条命令看清现状动手之前先查一遍能省掉后面“装了三遍还是提示已安装”的麻烦:: 64 位系统上x86 的安装记录被重定向到 WOW6432Node 下 reg query HKLM\SOFTWARE\Microsoft\VisualStudio\9.0\VC\VCRedist\x86 /v Installed reg query HKLM\SOFTWARE\WOW6432Node\Microsoft\VisualStudio\9.0\VC\VCRedist\x86 /v Installed :: WinSxS 里实际落地的程序集清单能看出装了哪些 build dir /b %SystemRoot%\WinSxS\Manifests\*VC90.CRT*.manifest第一条在纯 64 位系统上通常查不到因为 x86 的 redist 写入的是WOW6432Node分支所以两条都要敲。返回Installed REG_SZ 1就代表这个位数的包已经装过。第三条最有价值文件名里会带完整版本号和架构前缀x86_/amd64_一眼就能看出是 9.0.30729.17 还是后面的更新 build也能顺手确认 x86 和 x64 是不是都齐了。另外两个前置动作别省安装前重启一次把占用msvcr90.dll的进程尤其是你自己在调试的宿主进程、某些杀毒软件的文件监控清掉否则文件替换会失败并回滚如果机器上装过第三方“运行库合集”先看它是不是把 VC90 装成了残缺版本必要时用控制面板正常卸载别直接删目录。3. 安装 VC 2008 SP1从双击到静默批处理这套包的安装程序很老界面简陋到让人怀疑它是不是卡住了一个小窗口一个许可协议复选框一个 Install 按钮点下去十几秒没有进度条然后突然提示完成。第一次装的人很容易在这十几秒里连点两下触发第二个安装实例最后收到 1618 错误。3.1 手动安装顺序、权限和那十几秒的等待单机修一台机器时我按这个顺序走把压缩包解到本地目录别在压缩包里直接双击。老安装程序对临时路径里的中文和空格容忍度不高解到D:\redist\vc2008\这种纯英文短路径最省事。先装vcredist_x86.exe右键“以管理员身份运行”。即使是管理员账户也建议显式提权UAC 弹窗被误点“否”的话安装会静默失败。勾选许可协议复选框点 Install。这期间不要重复双击也不要开第二个安装程序。完成后不提示重启但注册表项和 WinSxS 落地需要一点时间。我一般等 30 秒再装 x64 那份。装vcredist_x64.exe同样提权。32 位系统跳过这一步硬装会直接报“不是有效的 Win32 应用程序”。两个都装完重启一次。不是为了安装程序是为了让已经加载了旧 DLL 的进程重新加载。有一点值得说清楚x64 包并不会顺带把 32 位那份装上反过来也一样。所以“我只装了 x64怎么 32 位程序还是报错”这个疑问答案就在这。3.2 静默安装批量部署用的批处理一台台点不现实几十台机器我统一用一个批处理放在和两个 exe 同一个目录里echo off setlocal enabledelayedexpansion :: 日志放在脚本同目录方便回收上来对比 set LOG%~dp0vc2008_install.log echo %DATE% %TIME% %LOG% :: /q 静默无界面/norestart 禁止自动重启生产机上必须加 %~dp0vcredist_x86.exe /q /norestart set RC_X86%errorlevel% echo x86 exit%RC_X86% %LOG% %~dp0vcredist_x64.exe /q /norestart set RC_X64%errorlevel% echo x64 exit%RC_X64% %LOG% :: 0成功 3010成功但需重启 1638已存在更高版本 1603安装失败 1618另一安装正在进行 if %RC_X86%0 if %RC_X64%0 ( echo RESULTOK %LOG% exit /b 0 ) echo RESULTCHECK_NEEDED %LOG% exit /b 1参数只有两个但含义要记牢/q是完全静默连许可协议都自动接受这是官方 redist 的既定行为企业内部批量部署都这么用/norestart是必须加的否则某些缺补丁的机器会被安装程序直接重启正在跑的采集任务就断了。返回码里3010和0一样算成功只是要安排一次重启窗口1638说明机器上已经有同版本或更新的 build不算失败脚本里应该当成功处理否则批量部署会误报一片红。如果/q之后行为异常、需要看底层日志可以直接把 exe 当压缩包打开7-Zip 之类工具能进去里面是 msi 加 cab。取出 msi 后用 msiexec 带日志跑失败原因会写得很清楚:: 从包里取出 msi 后执行/l*v 输出详细日志排 1935 这类错误只能靠它 msiexec /i vc_stdx86.msi /qn /norestart /l*v %TEMP%\vc90_x86.log/qn对应无界面/l*v表示输出最详细的日志含每个组件的安装结果日志默认在%TEMP%下出问题先搜Return value 3那一行上面几行就是真正的失败点。3.3 装完文件落在哪四个位置自查装完别急着跑程序先确认文件真落地了。VC90 的落地位置固定是这四处缺一处就说明没装全:: 1) 64 位 CRT64 位系统上才有 dir /b %SystemRoot%\System32\msvcr90.dll %SystemRoot%\System32\msvcp90.dll %SystemRoot%\System32\msvcm90.dll :: 2) 32 位 CRT64 位系统上在 SysWOW6432 位系统上就在 System32 dir /b %SystemRoot%\SysWOW64\msvcr90.dll :: 3) Side-by-Side 程序集本体和清单 dir /b /ad %SystemRoot%\WinSxS\x86_Microsoft.VC90.CRT_* dir /b /ad %SystemRoot%\WinSxS\amd64_Microsoft.VC90.CRT_* :: 4) 安装记录 reg query HKLM\SOFTWARE\WOW6432Node\Microsoft\VisualStudio\9.0\VC\VCRedist\x86 /v InstalledSystem32和SysWOW64里的三个 DLL 是给“没有 manifest 的老程序”兜底用的真正走 Side-by-Side 的程序加载的是WinSxS里带版本号的那份程序集。这也解释了一个常见困惑System32里的msvcr90.dll明明在程序还是报找不到——因为它要的是特定 build 的私有程序集不是系统目录里那份。MFC 相关的mfc90.dll、mfc90chs.dll属于另外的语言资源包普通 CRT 程序用不上不用因为缺它们而怀疑安装失败。4. 配置与集成把运行库放进你的发布包自己机器装好只是第一步。真正交付的时候问题永远出在“客户机上没装”。这里有三条路让用户自己装、在安装包里串一个 redist、或者干脆做应用本地部署。我一般按客户环境选。4.1 应用本地部署整个文件夹搬别只搬 DLL绿色版、免安装版最适合应用本地部署app-local把Microsoft.VC90.CRT整个文件夹放到 exe 同级目录加载器会优先用私有程序集客户机不装任何 redist 也能跑。关键在“整个文件夹”——里面必须包含Microsoft.VC90.CRT.manifest缺了它msvcr90.dll和msvcp90.dll可能还能勉强加载但msvcm90.dll托管 C 用的那部分会直接失败报的还是那句没有信息量的 0xc0150002。从一台已装好的机器上取程序集用这个循环避免手抄那串很长的目录名:: 从 WinSxS 取出 x86 的 VC90 CRT 程序集整目录复制并改名为标准私有程序集名 set DEST%~dp0deploy\Microsoft.VC90.CRT if exist %DEST% rd /s /q %DEST% for /d %%i in (%SystemRoot%\WinSxS\x86_Microsoft.VC90.CRT_*) do ( xcopy %%i %DEST%\ /E /I /Y nul ) dir /b %DEST%跑完目录里应该是msvcr90.dll、msvcp90.dll、msvcm90.dll加一个Microsoft.VC90.CRT.manifest四个文件。目录名必须是Microsoft.VC90.CRT程序集名写错等于没放。做 64 位程序时把循环里的x86_换成amd64_并且注意 x86 和 x64 的私有程序集不能混在同一目录得给不同位数的 exe 各配一份。注意应用本地部署只适合你能控制发布目录结构的场景。如果程序是从别的目录被拉起、或者有多个 exe 分散在不同层级私有程序集的位置很容易失效这种时候老老实实装 redist 更省心。4.2 安装包里串一个 redist检测在前安装在後用打包工具做安装程序时思路是“先检测缺了才装装完再装主程序”。以 Inno Setup 为例把两个 exe 放进redist目录[Files] Source: redist\vcredist_x86.exe; DestDir: {tmp}; Flags: deleteafterinstall Source: redist\vcredist_x64.exe; DestDir: {tmp}; Flags: deleteafterinstall [Run] ; Check 参数是自定义函数名返回 0 表示还没装才会执行安装 Filename: {tmp}\vcredist_x86.exe; Parameters: /q /norestart; \ StatusMsg: 正在安装 32 位 VC 2008 运行库...; \ Flags: waituntilterminated; Check: NeedVC90x86 Filename: {tmp}\vcredist_x64.exe; Parameters: /q /norestart; \ StatusMsg: 正在安装 64 位 VC 2008 运行库...; \ Flags: waituntilterminated; Check: NeedVC90x64三个参数决定成败waituntilterminated让安装程序等 redist 跑完再继续否则主程序会先启动、加载失败deleteafterinstall把临时 exe 清掉不然几十兆会一直留在客户机%TEMP%里Check挂检测函数避免每次升级安装都重跑一遍 redist重跑虽然多半返回 1638但会白等十几秒。检测逻辑就是读注册表那个Installed值RegQueryDWordValue(HKLM, SOFTWARE\WOW6432Node\Microsoft\VisualStudio\9.0\VC\VCRedist\x86, Installed, Value)返回 False 时才装。不用打包工具的场合用 3.2 那段批处理当“前置步骤”也能顶上只是没法自动判断是否已装。4.3 版本共存别为了“干净”去卸载旧的Side-by-Side 的规则是允许同一 CRT 的多个 build 并存所以机器上同时有 9.0.30729.17 和后面的更新 build 是正常状态不是“装重复了”。我见过运维为了清爽把旧版一个个卸掉结果把某个 manifest 写死旧版本的老控件一起送走了。什么时候该升级、什么时候该放着如果你的程序是自己编译的跟着最新的安全更新走重新编译时 manifest 会自动指向新 build如果是接手别人的老程序而 manifest 里写的是9.0.30729.17那就把这个 build 老老实实留着。有的安全更新会在WinSxS里额外注册策略程序集把旧版本请求重定向到新版本这种情况下旧 build 不装也能跑但这个重定向不是必然会出现的不能当作前提去规划。判断方法很直接在WinSxS\Manifests下找有没有对应的Policy清单没有就别抱侥幸。卸载也得讲方法。控制面板卸不掉提示“已安装此产品的更新版本”或直接报错时别去手工删WinSxS目录那地方删错一个程序集半个系统的程序都起不来。正确姿势是从原版 exe 里取出 msi用msiexec /x卸或者用系统的安装疑难解答先把注册信息理顺。5. 排查 VC 2008 的常见故障五个常见报错装完起不来先别急着重装。这几个报错的指向性其实很强按现象对号入座通常十分钟能定位。5.1 弹窗 0xc000007b位数错了不是文件坏了现象双击程序立刻弹出“应用程序无法正常启动(0xc000007b)”没有任何其他提示。原因这个错误码的本质是“映像格式无效”最常见的触发是 32 位进程拿到了 64 位 DLL或者反过来。典型场景客户机上只装了 x64 redist32 位 exe 去SysWOW64找不到对应的msvcr90.dll于是在别处搜到一个位数不对的版本加载器直接拒绝。另一种场景是应用本地部署时把 x86 和 x64 的程序集混在了同一个目录。解决用 2.1 的 PowerShell 脚本确认程序位数补装对应位数的包应用本地部署的把 x86 和 x64 的Microsoft.VC90.CRT分开放到各自 exe 旁边。补装完记得重启别指望已经加载过旧 DLL 的进程自己恢复。5.2 0xc0150002 或事件日志里的 SideBySide 错误现象程序启动失败提示“应用程序无法正常启动(0xc0150002)”或者事件查看器里出现来源为 SideBySide 的错误ID 常见 33 或 59描述里带一串程序集名和版本号。原因manifest 里写的 CRT 版本在系统里找不到。要么装的是 RTM 的 9.0.21022.x 而程序要 9.0.30729.x要么删掉了某个 build要么程序自带 manifest 但目录里缺Microsoft.VC90.CRT.manifest。解决把事件日志里那段完整程序集名抄下来版本号后四位就是缺的 build对着装对应版本的 redist。应用本地部署的检查私有程序集目录里四个文件是否齐全特别是那个.manifest。顺手确认程序集目录名拼写Microsoft.VC90.CRT少一个点都不行。5.3 安装回滚、报 1935 或 0x80070005现象安装走到一半进度回退最后提示安装失败或者干脆没有任何提示就退出。原因1935 一般是 Windows Installer 组件注册出错常见于系统盘空间不足、杀软拦截了 msi 的写操作、或者之前有安装被强行中断留下脏状态。0x80070005 是权限不足多出现在以普通用户身份运行、或组策略限制了 Windows Installer 的场景。解决先确认msiserver服务能启动磁盘剩余空间大于 1G临时关掉杀软的文件实时监控再装一次还是不行就取出 msi 用msiexec /i ... /l*v拿到详细日志搜Return value 3定位到具体组件。权限问题就用管理员账户跑别在远程会话里用映射驱动器上的临时目录。5.4 装完还提示缺 msvcr90.dll现象确认 redist 装成功了注册表也有记录程序还是报找不到msvcr90.dll。原因三种可能。一是装的是 RTM 版程序要 SP1二是程序自己带了一份 manifest 但目录里的 DLL 被替换成了不匹配的版本三是程序运行在受限目录比如某些沙箱环境加载器读不到WinSxS里的程序集。解决先看WinSxS\Manifests里有没有对应版本再检查程序目录下是不是残留了半套私有程序集只有 DLL 没 manifest 最容易出这种事有就清掉让系统走全局程序集。最后用进程监视工具看它到底在哪些路径找 DLL比猜快得多。5.5 提示“已安装此产品的更新版本”装不上也卸不掉现象重装时弹出这个提示直接退出想卸载又找不到入口或者卸载报错。原因机器上已经存在同版本或更高 build 的记录安装程序判定无需安装而卸载入口可能因为之前的非正常卸载丢了注册信息。解决这本来就不算错误先按 3.3 确认文件确实在能用就别折腾。确实要重装从 exe 里取 msi 用msiexec /x卸注册信息已经损坏的用系统自带的安装疑难解答先修复注册状态再重装。绝对不要手工删WinSxS里的程序集目录那是不可逆的破坏。6. 验证跑通三条检查确认 CRT 真的生效装完不验证等于没装。我判断一套 VC 2008 环境是否真的可用只看三件事文件在不在、注册记录对不对、目标程序能不能起来。前两条是静态检查第三条才是终局。检查项命令或方式期望结果32 位 CRT 落地dir /b %SystemRoot%\SysWOW64\msvcr90.dll输出文件名无“找不到文件”64 位 CRT 落地dir /b %SystemRoot%\System32\msvcr90.dll同上32 位系统跳过SideBySide 程序集dir /b /ad %SystemRoot%\WinSxS\x86_Microsoft.VC90.CRT_*至少一个带 9.0.30729 的目录安装记录reg query HKLM\SOFTWARE\WOW6432Node\Microsoft\VisualStudio\9.0\VC\VCRedist\x86 /v InstalledInstalled REG_SZ 1实跑验证启动那个原本报错的程序正常进入界面静态检查里WinSxS那条最有价值。它不光能确认装没装还能看出装的是哪个 build:: 列出所有 VC90 CRT 程序集目录目录名里的版本号就是实际可用的 build for /d %i in (%SystemRoot%\WinSxS\*_Microsoft.VC90.CRT_*) do echo %~nxi输出里出现x86_Microsoft.VC90.CRT_..._9.0.30729.6161_...这样的名字说明这个 build 可用x86_和amd64_两种前缀都在才叫两个位数齐了。我通常会把这条命令的输出和程序 manifest 里要求的版本对一遍——对不上就是还没装对不用往下试。实跑验证讲究一点不要在自己的开发机上跑通就算完。我在客户机上验收时一定会用干净的普通用户账户跑一遍因为管理员账户常常能看到一些普通用户看不到的路径再用进程监视工具确认它加载的msvcr90.dll来自WinSxS而不是某个来路不明的目录——这一步能提前发现私有程序集放错位置的隐患。程序起来了但功能异常比如某个导出函数调用失败那就是 build 不匹配的另一种表现回头按 5.2 查事件日志。从那以后我每次交付前都强制走一遍这三条WinSxS扫版本、注册表确认位数、用非管理员账户实跑一次。刚开始觉得麻烦被 0xc0150002 教育过两回之后就成肌肉记忆了。压缩包里 x86 和 x64 两个 exe 我习惯连同上面那段批处理放在同一个目录一起带走到现场解压、提权、执行日志回收上来一眼就能看出哪台没装成功。希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?