''' In Windows, dependencies of a DLL can be obtained from its PE import table. A useful Python solution is to use the pefile package, which reads the DLL without loading or executing it. It gives only direct dependencies. The pefile package does not guarantee the complete runtime dependency list. This code generates dependency tree by recursively inspecting each DLL. Install pefile: pip install pefile Run: python getDependenciesTreeDLL.py C:\Projects\dll_third_party.dll dir_1/ dir_2/ ''' from pathlib import Path import pefile def get_dependencies(path): """Get direct DLL dependencies of a PE file.""" try: pe = pefile.PE(str(path), fast_load=True) pe.parse_data_directories( directories=[ pefile.DIRECTORY_ENTRY["IMAGE_DIRECTORY_ENTRY_IMPORT"] ] ) dependencies = [] if hasattr(pe, "DIRECTORY_ENTRY_IMPORT"): for entry in pe.DIRECTORY_ENTRY_IMPORT: name = entry.dll.decode( "utf-8", errors="replace" ) dependencies.append(name) pe.close() return sorted(set(dependencies)) except Exception: return [] def find_dll(name, search_dirs): """ Find a DLL in the supplied directories. """ for directory in search_dirs: candidate = directory / name if candidate.exists(): return candidate return None def print_dependency_tree( dll_path, search_dirs, prefix="", visited=None ): if visited is None: visited = set() dll_path = Path(dll_path).resolve() # Prevent circular dependencies if dll_path in visited: return visited.add(dll_path) print(f"{prefix}{dll_path.name}") dependencies = get_dependencies(dll_path) for i, dependency in enumerate(dependencies): is_last = i == len(dependencies) - 1 branch = "└── " if is_last else "├── " child_prefix = " " if is_last else "│ " dependency_path = find_dll( dependency, search_dirs ) if dependency_path: print_dependency_tree( dependency_path, search_dirs, prefix + branch[:-4] + child_prefix, visited ) else: print( f"{prefix}{branch}" f"{dependency} [not found]" ) if __name__ == "__main__": import sys if len(sys.argv) < 2: print( "Usage: python dll_tree.py " " [search_directory ...]" ) sys.exit(1) dll = Path(sys.argv[1]).resolve() # Search the DLL's directory plus directories supplied # on the command line. search_dirs = [ dll.parent ] for directory in sys.argv[2:]: search_dirs.append( Path(directory).resolve() ) print_dependency_tree( dll, search_dirs )