Windows自动查找程序dll依赖
东东 Lv4

本文主要介绍在Windows开发中如何自动查找程序的dll依赖

Windows 程序在发布的时候往往需要很多第三方 dll 依赖, 而这些依赖一般都在开发环境中, 需要一个一个拷贝到程序目录中, 比较的麻烦. 有一些开发平台会提供程序的打包命令, 当用户执行打包命令时会自动将所有依赖拷贝到程序所在目录中, 例如: QT 的 windeployqt.exe 工具, 但你会发现 windeployqt 有时候并没有能够给出所有依赖, 它只是给出了与 QT 自身相关的依赖, 如果你使用了非 QT 的第三方库, 则 windeployqt 可能也找不到.

不过有一个较为实用的技巧是直接将开发环境中bin目录下的所有文件都拷贝到程序目录中,然后运行该程序, 程序运行后选择所有之前拷贝的文件并将其删除, 能够删掉的说明不是该程序的依赖, 最后留下的一定就是当前程序的依赖了, 如此一来程序的所有依赖就都凑齐了.

当然上面的技巧是一种比较笨的办法, 下面介绍的脚本可以较为方便地尽量凑齐所有依赖, 当然除了个别比较特殊难找的依赖外, 如果实在找不到那就只能手动复制了.

find_dll.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#!bash

notfounddlls='KERNEL32.dll'
dllbase=/mingw64/bin/

# @breif 对给定路径下的可执行文件进行依赖查找和拷贝
# @param $1 可执行文件所在的路径
# @return none
function find_dll
{
if [ "$1" == "" ]; then
return
fi

local path=$1

nc=1
while [ $nc -gt 0 ]; do
nc=0
# 遍历给定目录下的所有 .exe 和 .dll 文件
for f in $path/*.exe $path/*.dll; do
# 遍历当前 .exe 和 .dll 文件的所有 dll 依赖
for dep in $(strings $f | grep -i '\.dll$'); do
# 当前路径下还没有该 dll 依赖, 则进行处理
if [ ! -e $path/$dep ]; then
# 判断当前依赖是否是在 notfounddlls 列表中
# 在列表中就说明之前找过, 但是没有找打, 因此也不必再找了
echo $notfounddlls | grep -iw $dep >/dev/null
if [ $? -ne 0 ]; then
# 查找 dll 库是否有该 dll 依赖, 有则拷贝到给定目录下
# 没有就放到 notfounddlls 列表
dllloc=$(find $dllbase -iname $dep)
if [ ! -z "$dllloc" ]; then
cp $dllloc $path
echo "Copying "$(basename $dllloc)
nc=$(($nc + 1))
else
notfounddlls="$notfounddlls $dep"
fi
fi
fi
done
done
done

echo "System DLLS: "$notfounddlls
}

# main 函数
function main
{
local path=$PWD

if [ "$1" == "-h" ]; then
echo "Usage: $0 [path]"
echo " Find all dll dependencies of an executable file under a given <path>."
echo " If no path parameter is given, the current call path is used."
return
elif [ "$1" != "" ]; then
path=$path/$1
fi

find_dll $path
}

main $@

参考文献

Finding DLLs required of a Win exe on Linux (cross-compiled with mingw)?

源文件来自于

 评论