參考:
https://blog.csdn.net/u010205478/article/details/88682932
https://www.cnblogs.com/hbccdf/p/dllchecktoolandsyswow64.html
https://blog.csdn.net/norsd/article/details/81288681
現狀: 一個VS項目,build完成了,運行時卻報0xc000007b錯誤,無法運行!
查看依賴項
- 使用開始菜單,輸入"VS2015 本地工具命令提示符",運行之.
- 輸入
dumpbin /dependents [文件路徑]
,比如要查看c盤根目錄下的a.exe就輸入dumpbin /dependents "C:\a.exe"
- 發現有幾個依賴項;
檢查依賴項是否可以訪問到
- 使用Everything檢查這幾個依賴項是否存在系統路徑"C:\Windows\System32" and "C:\Windows\SysWOW64"里,以及exe同一目錄里等;
根據大佬分析,System32目錄存放的是64位的dll, SysWOW64目錄存放的是32位的dll. 32位應用程序(exe)等訪問System32目錄下的任何文件時,會被自動映射到SysWOW64目錄. 64位應用程序(exe)可以直接訪問兩個目錄.
檢查依賴項的版本是32位還是64位
- 如果所有依賴的dll都在能訪問到的路徑,那么可能是dll的版本與應用程序(32位)不匹配.使用denpends.exe軟件(Dependency Walker)可以查看到依賴項DLL的版本,
使用文本編輯器查看你已有dll的版本也可以: 第2行的PE后面跟的是d,表示64位DLL,如果跟的是L,表明是32位的DLL文件
- 把該DLL替換成32位版本即可.
奉勸打包工程的老師們,用心打包一下吧
本部分參考了 [Unable Access....404]
- 首先,打開
VS2015 本地工具命令提示符
,如果查看b.exe中加載了哪些動態庫,可以使用:dumpbin /imports b.exe >2.txt
, 此時exe文件所依賴的dll都會寫入2.txt。 - 將2.txt文件中dll文件名整理,只保留其中的dll文件,按行存儲;
- 按一下格式寫txt,其中,例如
D:\Opencv 2.4.10\opencv\build\x86\vc12\bin
為dll所在文件夾,C:\Users\Administrator\Desktop\test
為將要打包的文件路徑。
@for /f %%i in (2.txt) do if exist "D:\Opencv 2.4.10\opencv\build\x86\vc12\bin\%%i" copy "D:\Opencv 2.4.10\opencv\build\x86\vc12\bin\%%i" C:\Users\Administrator\Desktop\test
- 該格式為bat執行,2.txt中文件被存儲到目標文件夾。
參考https://blog.csdn.net/Q936795779/article/details/81667109/
- 將依賴動態庫復制到 exe 目錄下,很簡單的工作,用 bat 腳本自動實現。
- 分析依賴庫
- 找到對應的 dll 文件目錄,找不到則記錄
- 復制到當前目錄下
- 分析結果可能不夠,提供補充工具,根據名字找到並復制到當前目錄下
- get_dll.bat
需搭配add_process.bat使用,即保持同一目錄
功能:
復制exe到該目錄下
解析dll依賴
復制dll到該目錄下
@echo off
echo 應用: 利用vs的dumpbin工具解析依賴dll,並復制到.\dll_date目錄下。
echo 原理: 用vs的dumpbin解析dll依賴,where找到dll路徑,copy過來。
echo 使用: 1. cmd下 this + exe file dir
echo 2. 提示輸入路徑。
echo 補充: 運行時可能仍然缺少某些dll文件,運行add_dll.bat手動補充。
SETLOCAL ENABLEDELAYEDEXPANSION
set exe_path=%1
set exe_name=%~n1%~x1
set /p copy_exe=復制%1到 %~p0 exe_%date:~5,10% 下(y or n)?
if %copy_exe%==y ( md .\exe_%date:~5,10% 2>nul
copy %1 .\exe_%date:~5,10%\%exe_name%)
set dll_path=dll_%date:~5,10%
set /p vs_root_path=visual studio 安裝根目錄(eg.E:\VS2015):
::set vs_root_path=E:\VS2015
set dumpbin_path=%vs_root_path%\VC\bin\
echo Step1. set dumpbin root: %dumpbin_path%
echo Step2. set exe file path: %exe_path%
md .\%dll_path%>nul
echo Step3. 開始解析依賴dll
%dumpbin_path%dumpbin.exe /dependents %exe_path% | findstr "\.dll$" >.\%dll_path%\_dependent_dll_log.txt
echo 解析完畢,總計
type .\%dll_path%\_dependent_dll_log.txt | find /v /c ""
set /p showlog=展示全部(y or n)?
if %showlog%==y ( type .\%dll_path%\_dependent_dll_log.txt)
echo Step4. 復制全部dll到 .\%dll_path%\
set /p copyAll=確定(y or n)?
if not %copyAll%==y ( echo 清除緩存
del .\%dll_path%\*.*
rd .\%dll_path%
echo 清理完畢,再見
goto end )
for /f %%i in (.\%dll_path%\_dependent_dll_log.txt) do (
WHERE %%i 1> .\%dll_path%\temp.txt 2>nul
if errorlevel 1 ( echo 找不到%%i,記錄於.\%dll_path%\copy_error_log.txt
echo %%i>>.\%dll_path%\copy_error_log.txt )
call add_process.bat %%i -off)
del %dll_path%\temp.txt
echo 復制工作結束
:end
pause
- add_process.bat
附加處理工具,主要工作是獲得txt文本中第一行,並復制dll文件
@echo off
set dll_name=%~n1%~x1
for /f %%j in (.\%dll_path%\temp.txt) do ( if %2==-on echo 開始復制,復制對象:%%j
copy %%j .\dll_%date:~5,10%\%dll_name%
goto add_end )
:add_end
::end add_process to break for loop and get only the first line.
- add_dll.bat
補充工具
功能:
根據輸入dll名字,自動查找並復制到該目錄下dll存放文件夾中
使用:
直接運行即可
@echo off
set dll_path=dll_%date:~5,10%
set temp=%dll_path%\temp.txt
md .\%dll_path% 2>nul
echo 應用:復制dll文件到%dll_path%目錄下
:add_start
set /p dll_name=輸入dll文件名(eg. gflags.dll),q to quit:
if %dll_name%==q ( goto add_end)
where %dll_name% 2>nul 1>%temp%
if errorlevel 1 ( echo 未找到%dll_name%,請重新輸入
goto add_start )else ( echo 找到%dll_name% 於
type %temp% )
call add_process.bat %dll_name% -on
set /p flag=繼續復制dll文件(y or n)?
if %flag%==y ( goto add_start )else ( echo 再見)
del .\%temp%
:add_end
pause
缺哪個DLL,就去http://api.256file.com/這個網站搜索,后面一般都有需要安裝什么軟件..