1、qt
查找项目中使用到的qt动态链接库;
步骤如下
①打开项目使用的windeployqt工具(qt自带的工具);
②进入到文件夹所在目录;使用 cd 命令
③使用命令:windeployqt Name.exe(在目标文件夹所在目录下执行该命令)
但是由于我的QT使用的是MSVC编译器,会用到一些VC的库,使用qt的命令行时会提示我
warning:Cannot find Visual Studio installation directory,VCINSTALLDIR is not set.
解决方案1
win+R,输入QT安装目录下windeployqt.exe的路径,然后空格,再加上项目Release的路径。
我的是:C:\Qt\Qt5.13.1\5.13.1\msvc2015_64\bin\windeployqt.exe D:\GIICS\qtReleaseDemo\x64\Release\qtReleaseDemo.exe,供参考。
然后会有这个warning,这个在中间很难被发现,要注意!
找到msvcp140d.dll(我是VS2015,所以是140),复制它的路径添加到环境变量中。我的路径是C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\redist\debug_nonredist\x64\Microsoft.VC140.DebugCRT\msvcp140d.dll,添加环境变量时,到VC就可以了,后面的不要。
关闭cmd重新打开(一定要先关闭之前打开的,然后重新打开),输入第三步的路径,C:\Qt\Qt5.13.1\5.13.1\msvc2015_64\bin\windeployqt.exe D:\GIICS\qtReleaseDemo\x64\Release\qtReleaseDemo.exe,回车就行了。
看到Release文件夹下多出了QT的很多dll和vcredist_x64.exe就行了。把这个文件夹放到一个全新的计算机也能跑起来,不过得在计算机上先安装图中的vcredist.exe。
应用windeploy添加环境变量时尽量只有一个 ,当两个时你用windeployqt +可执行名时 打包可能会出错,如你使用的时msvc2019_64建立的Qt项目
你打包时可以使用的是mingw_64打包的文件。移植到其他电脑上时就会报错。
所以你可以留有一个环境变量的路径 记得重启
方法二
首先将配置改为Release。
接下来重新生成项目。
然后从工程目录/x64/Release/中便可找到生成的exe文件。
若想运行该exe文件,需将其需要的各个dll文件与其放在同一文件夹中。
这里主要需要qt的一些dll文件,可在qt安装目录里msvc2017_64/bin文件夹中找到。
使用windeployqt这个命令应该都知道,
将release版本exe复制拷贝到一个单独目录;
4.2打开QT下MSVC 2017控制台,切换到刚才exe所在目录;
4.3再使用 Qt 自带的 windeployqt 工具命令,其语法格式为:
windeployqt 可执行程序名
4.4可以看到windeployqt 工具已经将程序所依赖的qt环境已经复制到当前目录。
还有就是进入VS的安装路径
C:\ProgramFiles(x86)\MicrosoftVisualStudio14.0\Common7\IDE\RemoteDebugger\x64
你是x64开发的就选x64,要不然就选x86.
去把如下运行库拷出来放到exe路径下,要不然去遇到运行库错误,就异常尴尬了!
api-ms-win-core-console-l1-1-0.dll
api-ms-win-core-datetime-l1-1-0.dll
api-ms-win-core-debug-l1-1-0.dll
api-ms-win-core-errorhandling-l1-1-0.dll
api-ms-win-core-file-l1-1-0.dll
api-ms-win-core-file-l1-2-0.dll
api-ms-win-core-file-l2-1-0.dll
api-ms-win-core-handle-l1-1-0.dll
api-ms-win-core-heap-l1-1-0.dll
api-ms-win-core-interlocked-l1-1-0.dll
api-ms-win-core-libraryloader-l1-1-0.dll
api-ms-win-core-localization-l1-2-0.dll
api-ms-win-core-memory-l1-1-0.dll
api-ms-win-core-namedpipe-l1-1-0.dll
api-ms-win-core-processenvironment-l1-1-0.dll
api-ms-win-core-processthreads-l1-1-0.dll
api-ms-win-core-processthreads-l1-1-1.dll
api-ms-win-core-profile-l1-1-0.dll
api-ms-win-core-rtlsupport-l1-1-0.dll
api-ms-win-core-string-l1-1-0.dll
api-ms-win-core-synch-l1-1-0.dll
api-ms-win-core-synch-l1-2-0.dll
api-ms-win-core-sysinfo-l1-1-0.dll
api-ms-win-core-timezone-l1-1-0.dll
api-ms-win-core-util-l1-1-0.dll
api-ms-win-crt-conio-l1-1-0.dll
api-ms-win-crt-convert-l1-1-0.dll
api-ms-win-crt-environment-l1-1-0.dll
api-ms-win-crt-filesystem-l1-1-0.dll
api-ms-win-crt-heap-l1-1-0.dll
api-ms-win-crt-locale-l1-1-0.dll
api-ms-win-crt-math-l1-1-0.dll
api-ms-win-crt-multibyte-l1-1-0.dll
api-ms-win-crt-private-l1-1-0.dll
api-ms-win-crt-process-l1-1-0.dll
api-ms-win-crt-runtime-l1-1-0.dll
api-ms-win-crt-stdio-l1-1-0.dll
api-ms-win-crt-string-l1-1-0.dll
api-ms-win-crt-time-l1-1-0.dll
api-ms-win-crt-utility-l1-1-0.dll
concrt140.dll
msvcp140.dll
ucrtbase.dll
vcruntime140.dll
如遇0xc0000007b,应该是你没把上面这些库放完整。
注意concrt140.dll
msvcp140.dll
vcruntime140.dll(我是VS2015,所以是140)
一、procexp
1.procexp 免费
https://docs.microsoft.com/en-us/sysinternals/downloads/process-explorer
procexp.exe查看32位程序,procexp64.exe 查看64位程序
2.View->Lower Pane View DLLs 显示dll窗口
在exe所在目录新建文本文档(后续会改为批处理程序bat后缀),自定义命名,如AutoGetDLL.txt,并添加以下内容:
for /r "%cd%" %%i in (*.exe) do (
D:\Qt\6.2.4\msvc2019_64\bin\windeployqt.exe "%%~nxi")
pause
注意:批处理语句中的C:\Qt\Qt5.7.0\5.7\mingw49_32\bin\windeployqt.exe是windeployqt.exe实际所在路径,在QT安装目录下搜索windeployqt.exe即可定位所在路径。
修改txt后缀为bat:
运行bat(批处理)程序即可将程序依赖的DLL拷贝至程序所在目录:
exe依赖的dll拷贝成功,程序正常运行!
这就需要使用批处理脚本了,功能是将当前脚本所在目录的所有exe文件所依赖的QT库都拉进来,完美解决QT依赖库拷贝问题,脚本如下:
echo off
echo Setting up environment for Qt usage...
set PATH=D:\Qt\6.2.4\msvc2019_64\bin;%PATH% rem 此行目录为QT的安装目录,需要自行调整
echo bat与exe放在同一个目录
for /f "delims=" %%A in ('dir /b *.exe') do windeployqt %%A
echo pause
Windows下,exe文件在设计实现时可能依赖某些动态库(*.dll文件),这些在调试台调试或在本机运行因为指定了包含库文件或者指定了环境变量,使得运行时可以找到并调用这些文件。但是环境变化,很容易找不到。报错找不到dll文件。
对现成的exe文件,解决方法一般是根据报错信息,找到dll文件,设置好环境变量,或者直接复制dll文件到exe所在目录解决依赖问题。
其实主要是编译得到exe文件想要移到其他电脑上运行,解决依赖库问题。
将依赖动态库复制到 exe 目录下,很简单的工作,用 bat 脚本自动实现。
dumpbin.exe /dependents xxx\xxx.exe
即可得到依赖库信息。findstr "\.dll$" test.txt
即可匹配到具有“.dll”字符串的行。用通道和重定向可以很方便输出全部为dll名字的 txt 文本
where xxx.dll
copy realdir\xxx.dll .\dlls\xxxxx.dll
a. get_dll.bat
需搭配add_process.bat使用,即保持同一目录
功能:
@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
b. 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.
c. add_dll.bat
补充工具
功能:
使用:
@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
用到的bat语法
1) 变量与赋值 set定义,%名字%调用, set /p 提示输入
%加数字是批处理后面的参数,以空格间隔。0表示本身的完全路径。
利用%数字 和 其他处理手段,可以方便地处理参数和路径 https://www.jb51.net/article/52744.htm
2) 管道与重定向 | > >> >& 1> 2>
|组合 >重定向 >>追加重定向
数字表示句柄,代表信息级别。1<&3 3的指向复制给1 1> 一般为标准输出级别 2为错误信息级别 0为输入。
>nul 是windows下空设备。
3) if else。if [not] == if [not] exist "%filepath%" ()
需要有空格才能识别else以及括号里的命令。
4) for 循环与内部变量
一般的环境变量需延迟定义。这里失败了,用了别的方法,call第二个bat。
5) call goto
call调用第二个bat 结束后返回。使for循环有效continue。
goto跳转到其他代码,一旦跳出for将不再返回,为break。
对于for循环内部循环赋值变量,可见这个变量是临时性的。传入第二个for循环进行处理,并且这里不是环境变量,而是循环变量。
天然支持随循环变化。
主要用来解决:
第一个for循环得到文本内每一行,第二个循环得到由一个循环的一行字符串处理得到的一个新文本的第一行。两个for循环一样的语法,
只是第二个for循环只需得到第一行即可,故而goto,break for。
goto对循环非常非常轻松地实现。
6) 字符串处理
findstr + 正则表达式。其以行为处理单位。
7) 使用errorlevel
判断命令是否执行成功
还想做的
把dumpbin独立出来
cmder是一个增强型命令行工具,不仅可以使用windows下的所有命令,更爽的是可以使用linux的命令,shell命令。
GitHub - cmderdev/cmder: Lovely console emulator package for Windows
Releases · cmderdev/cmder · GitHub
下载的时候,会有两个版本,分别是mini与full版;唯一的差别在于有没有内建msysgit工具,这是Git for Windows的标准配备;全安装版 cmder 自带了 msysgit, 压缩包 23M, 除了 git 本身这个命令之外, 里面可以使用大量的 linux 命令;比如 grep, curl(没有 wget); 像vim, grep, tar, unzip, ssh, ls, bash, perl 对于爱折腾的Coder更是痛点需求。
直接解压到某个目录就可以了,点击Cmder.exe运行。
在系统变量添加
最后在Path添加一条斜体文字
%CMDER_HOME%
配置环境变量后,在管理员权限的终端输入以下语句。
Win8或者Win10可以直接 win+x 再按 a 键进入。
Cmder.exe /REGISTER ALL
配置好后,任意文件夹右键
快捷键 Ctrl + t 后勾选
快捷键:win + alt + p
或者在右下角图标,右击
之前在网找了好多方法,可是都解决不了,很多人在在Environment里添加set LANG=zh_CN.UTF-8来解决中文乱码的问题,可是我用这个方法并没有成功,可能是环境的原因吧,我的系统是win10的。
最后找到解决办法:
Settings->Startup->Environment 添加
set LANG=zh_CN.UTF-8
set LC_ALL=zh_CN.utf8
重启Cmder,发现使用ls,中文正确显示了。
Win + ALT + P,唤出设置界面直接去掉右边那个monospce的对勾即可
内置了几款不错的主题,当然如果你觉得不合适,当然也支持自己设定。
ls命令不支持中文
win+alt+p
打开设置面板,找到Startup -> Envrioment
选项
在下面的文本框里添加一行set LANG=zh_CN.UTF-8
然后重启cmder
然后用ls命令查看目录下的文件,带中文的文件名都能正常显示了。
添加 cmder 到右键菜单
首先打开具有管理员权限的终端,快捷键Ctrl + t
勾选Run as current user
和Run as administrator
这两 项,然后点start开启,然后在命令行输入Cmder.exe /REGISTER ALL
现在在文件夹上右键点击Cmder here
就能在cmder里进入该目录
cmder默认的命令提示符是 λ ,如果想改成常见的 $ ,具体操作如下:
打开cmder安装目录下的\vendor\clink.lua文件找到lambda = "λ"
和lambda = "("..env..") λ"
把λ替换成$
然后重启cmder即可,但powerShell需要另行设置
打开cmder安装目录下的\vendor\profile.ps1文件找到λ
和λ
和Microsoft.PowerShell.UtilityWrite-Host "`nλ " -NoNewLine -ForegroundColor "DarkGray"把λ替换成$ ,然后重启cmder即可
win+alt+p
打开设置面板,找到Startup -> Tasks
选项,在右侧选中{cmd::Cmder}
把
cmd /k "%ConEmuDir%..init.bat" 修改成 cmd /k "%ConEmuDir%..init.bat" -new_console:d:E:\www
即可。E:\www
就是我们指定的默认打开目录
cmder还增加了alias功能,它让你用短短的指令执行一些常见但指令超长又难以记忆的语法;比如 ls cls等等
打开cmder安装目录下的\config\user-aliases.cmd文件
下面是我自己定义的常用的
st="D:\Sublime Text 3\sublime_text.exe" //输入st打开Sublime Text 3编辑器 w=cd /d E:/www //输入w跳转到E盘下的www目录 ..=cd .. //输入..返回上一级文件夹 wp=.\node_modules\.bin\webpack $* //如果webpack不是全局安装而是安装在项目下webpack命令不能直接用, //需要.\node_modules\.bin\webpack调用,每次都这样写太麻烦。 //现在只要输入wp就可以用webpack命令
如上图示编号的部分说明如下:
1, Cmder常用快捷键
2, 可在视窗内搜寻画面上出现过的任意关键字。
3, 新增页签按钮。
4, 切换页签按钮。
5, 锁定视窗,让视窗无法再输入。
6, 切换视窗是否提供卷轴功能,启动时可查询之前显示过的内容。
7, 按下滑鼠左键可开启系统选单,滑鼠右键可开启工具选项视窗。 Win+Alt+P :开启工具选项视窗。
验证下 ldd+ 可执行文件名
ldd untitled5.exe
没问题开始下面操作不能使用看是否配置正确
启动任务我用的是 bash as Admin
准备一个.sh脚本
比如我的 untitled5.sh
#!/bin/sh
exe="untitled5" #需要发布的程序名称
pwd="C:/Users/a7357/Documents/build-untitled5-Qt_6_2_4_msvc2019_64-Debug/debug/dll" #所建文件夹的路径
files=$(ldd $exe | awk '{if (match($3,"/")){ printf("%s "),$3 } }')
$(mkdir $pwd)
for Variable in ${files[@]}
do
cp $files $pwd
done
exe需要改为你程序的名字
pwd 改为你需要生成的路径
执行 ./ +你的.sh脚本文件名
./untitled5.sh
运行后你会发现所需要的dll会复制到该路径下,配上qt自带的windepyqt.exe 在移到其他电脑上运行基本没任何毛病