3.3 批量拷贝依赖到指定目录

发布于:2025-07-01 ⋅ 阅读:(23) ⋅ 点赞:(0)

一、查看程序依赖

Dependency Walker官网dependencywalker

下载:
在这里插入图片描述

打开dll或exe文件(关闭展开)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

将上面拷贝的依赖路径保存到dlls.txt文件

d:\program\msys64\mingw64\bin\LIBFDK-AAC-2.DLL
d:\program\msys64\mingw64\bin\LIBGCC_S_SEH-1.DLL
d:\program\msys64\mingw64\bin\LIBICONV-2.DLL
d:\program\msys64\mingw64\bin\LIBLZMA-5.DLL
d:\program\msys64\mingw64\bin\LIBMP3LAME-0.DLL
d:\program\msys64\mingw64\bin\LIBSTDC++-6.DLL
d:\program\msys64\mingw64\bin\LIBVA.DLL
d:\program\msys64\mingw64\bin\LIBWINPTHREAD-1.DLL
d:\program\msys64\mingw64\bin\LIBX264-164.DLL
d:\program\msys64\mingw64\bin\LIBX265-215.DLL

二、使用python脚本拷贝依

2.1 使用powershell脚本拷贝

# tree copy_dll/
copy_dll/
├── copy_dll.ps1  # 拷贝脚本
├── dlls          # 存储依赖的目录
└── dlls.txt      # 使用Dependency Walker拷贝的依赖路径

copy_dll.ps1脚本内容:

# 复制DLL文件到指定目录,并将文件名转换为小写
param (
    [Parameter(Mandatory=$true)]
    [string]$TargetDir
)

function Copy-DLLs {
    param (
        [string]$TargetDir
    )

    # 确保目标目录存在(支持相对路径)
    $fullTargetPath = $TargetDir
    if (-not [System.IO.Path]::IsPathRooted($TargetDir)) {
        # 如果是相对路径,转换为绝对路径
        $currentDir = Get-Location
        $fullTargetPath = Join-Path -Path $currentDir -ChildPath $TargetDir
    }

    if (-not (Test-Path -Path $fullTargetPath)) {
        New-Item -Path $fullTargetPath -ItemType Directory -Force | Out-Null
        Write-Host "创建目标目录: $fullTargetPath"
    }

    # 更可靠地获取脚本目录
    $scriptPath = $PSCommandPath
    if (-not $scriptPath) {
        # 如果$PSCommandPath为空,尝试使用$PSScriptRoot
        $scriptDir = $PSScriptRoot
        if (-not $scriptDir) {
            # 如果$PSScriptRoot也为空,使用当前目录
            $scriptDir = Get-Location
        }
    } else {
        $scriptDir = Split-Path -Parent $scriptPath
    }
    
    $dllFilePath = Join-Path -Path $scriptDir -ChildPath "dlls.txt"
    Write-Host "使用DLL列表文件: $dllFilePath"

    try {
        if (-not (Test-Path -Path $dllFilePath)) {
            throw "找不到DLL列表文件: $dllFilePath"
        }
        
        $dllPaths = Get-Content -Path $dllFilePath -ErrorAction Stop

        # 复制每个DLL文件
        $successCount = 0
        $failedFiles = @()

        foreach ($dllPath in $dllPaths) {
            if ([string]::IsNullOrWhiteSpace($dllPath)) {
                # 跳过空行
                continue
            }

            $dllName = Split-Path -Leaf $dllPath
            # 将文件名转换为小写
            $dllNameLower = $dllName.ToLower()
            $targetPath = Join-Path -Path $fullTargetPath -ChildPath $dllNameLower

            try {
                Copy-Item -Path $dllPath -Destination $targetPath -Force -ErrorAction Stop
                Write-Host "已复制: $dllPath -> $targetPath"
                $successCount++
            }
            catch {
                # 修复语法错误:分开显示错误信息
                Write-Host "复制失败: '$dllPath'" -ForegroundColor Red
                Write-Host "错误信息: $($_.Exception.Message)" -ForegroundColor Red
                $failedFiles += @{Path = $dllPath; Error = $_.Exception.Message}
            }
        }

        # 打印复制结果摘要
        Write-Host ""
        Write-Host "复制完成! 成功: $successCount, 失败: $($failedFiles.Count)"

        if ($failedFiles.Count -gt 0) {
            Write-Host ""
            Write-Host "失败的文件:" -ForegroundColor Red
            foreach ($file in $failedFiles) {
                Write-Host "  - '$($file.Path)'" -ForegroundColor Red
                Write-Host "    错误: $($file.Error)" -ForegroundColor Red
            }
        }
    }
    catch {
        Write-Host "错误: $($_.Exception.Message)" -ForegroundColor Red
        return $false
    }

    return $true
}

# 主函数
Copy-DLLs -TargetDir $TargetDir

脚本使用

.\copy_dll.ps1 -TargetDir "dlls"

在这里插入图片描述

2.2 使用python脚本拷贝

# tree copy_dll/
copy_dll/
├── copy_dll.py  # 拷贝脚本
├── dlls          # 存储依赖的目录
└── dlls.txt      # 使用Dependency Walker拷贝的依赖路径

copy_dll.py文件内容:

import os
import shutil
import sys

def copy_dlls(target_dir):
    # 确保目标目录存在
    if not os.path.exists(target_dir):
        os.makedirs(target_dir)
        print(f"创建目标目录: {target_dir}")
    
    # 读取dlls.txt文件
    dll_file_path = os.path.join(os.path.dirname(__file__), "dlls.txt")
    
    try:
        with open(dll_file_path, 'r') as f:
            dll_paths = f.read().splitlines()
        
        # 复制每个DLL文件
        success_count = 0
        failed_files = []
        
        for dll_path in dll_paths:
            if not dll_path.strip():  # 跳过空行
                continue
                
            dll_name = os.path.basename(dll_path)
            # 将文件名转换为小写
            dll_name_lower = dll_name.lower()
            target_path = os.path.join(target_dir, dll_name_lower)
            
            try:
                shutil.copy2(dll_path, target_path)
                print(f"已复制: {dll_path} -> {target_path}")
                success_count += 1
            except Exception as e:
                print(f"复制失败 {dll_path}: {str(e)}")
                failed_files.append((dll_path, str(e)))
        
        # 打印复制结果摘要
        print(f"\n复制完成! 成功: {success_count}, 失败: {len(failed_files)}")
        
        if failed_files:
            print("\n失败的文件:")
            for file_path, error in failed_files:
                print(f"  - {file_path}: {error}")
                
    except Exception as e:
        print(f"错误: {str(e)}")
        return False
        
    return True

def main():
    # 检查命令行参数
    if len(sys.argv) != 2:
        print("用法: python copy_dll.py <目标目录>")
        return
    
    target_dir = sys.argv[1]
    copy_dlls(target_dir)

if __name__ == "__main__":
    main()

脚本使用:

python .\copy_dll.py dlls

在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到