#include "dll_handle.h" #include #include #include #include #include #include #include namespace fs = boost::filesystem; bool DllHandle::read_ini(const std::string& purpose_dir) { no_dlls_.clear(); exe_dlls_.clear(); fs::path cur_exe = boost::dll::program_location(); fs::path config_path = cur_exe.parent_path().append("config.txt"); if (!fs::exists(config_path)) { std::cout << "配置文件不存在,不进行设置。" << std::endl; return false; } std::ifstream in(config_path.string(), std::ios::in); if (!in.is_open()) { std::cout << "打开配置文件失败:" << cur_exe.string() << ", 不进行设置。\n"; return false; } std::list dirs{}; // dirs.push_back(purpose_dir); std::string tmp{}; int add_status = 0; while (std::getline(in, tmp)) { dirs.push_back(tmp); } in.close(); for (const auto& data : dirs) { if (!fs::exists(data) || !fs::is_directory(data)) { continue; } for (auto const& entry : fs::recursive_directory_iterator(data)) { if (!entry.is_regular_file() || entry.path().extension().string() != ".dll") { continue; } DllInfo info; info.name = entry.path().filename().string(); info.full_path = entry.path().string(); no_dlls_.push_back(info); } } handle_multi_dll(); for (auto const& entry : fs::recursive_directory_iterator(purpose_dir)) { if (!entry.is_regular_file() || entry.path().extension().string() != ".dll") { continue; } DllInfo info; info.name = entry.path().filename().string(); info.full_path = entry.path().string(); exe_dlls_.push_back(info); } return true; } std::list DllHandle::get_dependents(const std::string& binary) { std::string cmd = "dumpbin /DEPENDENTS " + binary; std::string result = CmdOpr::exec_cmd(cmd); std::list dlls{}; std::list tmp{}; boost::split(tmp, result, boost::is_any_of("\n")); for (const auto& data : tmp) { if (!boost::contains(data, ".dll") || boost::contains(data, "Dump")) { continue; } std::string dllname(data); boost::trim(dllname); dlls.push_back(dllname); } return dlls; } // 将字符串转换为小写形式 std::string toLower(const std::string& str) { std::string result = str; std::transform(result.begin(), result.end(), result.begin(), ::tolower); return result; } bool DllHandle::find_dll(const std::string& name, DllInfo& info) { bool find = false; // 先在 exe 所在的目录找。 for (const auto& data : exe_dlls_) { if (toLower(name) != toLower(data.name)) { continue; } info.name = name; info.full_path = data.full_path; find = true; break; } // 如果找到了就不往下找了 if (find) { return true; } for (const auto& data : no_dlls_) { if (toLower(name) != toLower(data.name)) { continue; } info.name = name; info.full_path = data.full_path; find = true; break; } return find; } // 手动筛选多个dll的情况 void DllHandle::handle_multi_dll() { simple_dlls.clear(); for (const auto& data : no_dlls_) { simple_dlls[toLower(data.name)].push_back(data); } for (auto& data : simple_dlls) { if (data.second.size() > 1) { std::cout << "========================\n"; std::cout << "多个重名的dll,选择哪一个?\n"; int index = 0; for (auto& dll : data.second) { dll.index = ++index; std::cout << dll.index << ":" << dll.full_path << ".\n"; } std::string input{}; std::cin >> input; int select = std::stoi(input); data.second.remove_if( [&](const DllInfo& info) { return info.index != select; }); } } no_dlls_.clear(); for (const auto& data : simple_dlls) { no_dlls_.push_back(data.second.front()); } } bool DllHandle::is_have(const std::list& vec, const std::string& name) { bool find = false; for (const auto& data : vec) { if (toLower(data.name) != toLower(name)) { continue; } find = true; break; } return find; } void DllHandle::copy_dll(const std::string& purpose_dir, const std::list& tasks) { fs::path report_dir = fs::path(purpose_dir).parent_path(); auto now = std::chrono::system_clock::now(); std::time_t currentTime = std::chrono::system_clock::to_time_t(now); std::tm timeInfo; localtime_s(&timeInfo, ¤tTime); char buffer[256]{}; std::strftime(buffer, sizeof(buffer), "report_%Y%m%d%H%M%S.txt", &timeInfo); std::string report_name = report_dir.append(buffer).string(); std::ofstream out(report_name, std::ios::out); if (!out.is_open()) { std::cout << "打开报告文件:" << report_name << "失败,结束执行。\n"; return; } for (const auto& data : tasks) { fs::path des = fs::path(purpose_dir).append(data.name); if (fs::exists(des)) { std::string s = "跳过已存在的文件:" + des.string(); out << s << "\n"; std::cout << s << "\n"; } else { fs::copy(data.full_path, des); std::string s = "复制文件:" + data.full_path; out << s << "\n"; std::cout << s << "\n"; } } out.close(); }