// // Created by taynpg on 24-8-6. // #include "FunctionImp.h" #include "data.hpp" #include <filesystem> #include <fstream> #include <wx/base64.h> #include <wx/filename.h> #include <wx/log.h> #include <wx/msgdlg.h> #include <wx/stdpaths.h> #include <wx/textfile.h> #include <wx/tokenzr.h> namespace fs = std::filesystem; CFunPack::CFunPack() = default; bool CFunPack::gen(const wxString& bin, const wxString& out_dir, const wxArrayString& dirs) { auto ret_source = get_depend_on(bin, dirs); auto result = parse_result(ret_source); return handle_copy(result, out_dir.ToStdString()); } wxArrayString CFunPack::get_depend_on(const wxString& bin, const wxArrayString& dirs) { filename_ = fs::path(bin.ToStdWstring()).filename().wstring(); wxArrayString array; wxString cmd; if (!dirs.empty()) { cmd.append("export LD_LIBRARY_PATH=$LD_LIBRARY_PATH"); for (const auto& data : dirs) { cmd.append(":" + data); } } cmd.append(" && ldd " + bin); FILE* pf = nullptr; if ((pf = popen(cmd.c_str(), "r")) == nullptr) { return array; } char buffer[1024]{}; wxString result{}; while (std::fgets(buffer, sizeof(buffer), pf)) { result.append(buffer); } array = wxStringTokenize(result, wxT("\t"), wxTOKEN_DEFAULT); return array; } std::list<wxString> CFunPack::parse_result(const wxArrayString& array) { std::list<wxString> ret; wxArrayString simlog; wxArrayString bk_arry = array; for (auto& data : bk_arry) { if (data.empty()) { continue; } if (data.Contains("not found")) { simlog.push_back(wxT("未找到依赖:" + data)); continue; } data.Replace("=>", ""); wxArrayString tokens = wxStringTokenize(data, " "); wxString dy; if (tokens.size() == 4) { dy = tokens[2]; } if (tokens.size() == 3) { dy = tokens[1]; } if (dy.starts_with("/lib")) { continue; } if (!dy.empty()) { ret.push_back(dy); } } return ret; } bool CFunPack::handle_copy(const std::list<wxString>& rets, const wxString& dest_dir) { std::vector<fs::path> need_copy; for (const auto& item : rets) { // fs::path item_path(item); // if (fs::is_symlink(item.ToStdString())) { // auto real = fs::read_symlink(item.ToStdWstring()); // auto read_full = fs::path(item).parent_path().append(real.wstring()); // need_copy.push_back(read_full); // wxMessageBox(wxString(read_full.wstring())); // } need_copy.push_back(item.ToStdWstring()); } dest_dir_ = fs::path(dest_dir.ToStdWstring()).append(filename_.ToStdWstring()).wstring(); fs::create_directories(dest_dir_.ToStdWstring()); for (const auto& item : need_copy) { std::wstring new_path = fs::path(dest_dir_.ToStdWstring()).append(item.filename().wstring()).wstring(); fs::copy_file(item, new_path, fs::copy_options::overwrite_existing); } return true; } wxString ReadFileAndEncodeBase64(const wxString& filePath) { // 打开文件 wxFile file(filePath, wxFile::read); if (!file.IsOpened()) { wxLogError("Failed to open file: %s", filePath); return wxString(); } // 获取文件大小 wxFileOffset fileSize = file.Length(); if (fileSize <= 0) { wxLogError("File is empty or invalid: %s", filePath); return wxString(); } // 读取文件数据到wxMemoryBuffer wxMemoryBuffer buffer(fileSize); file.Read(buffer.GetData(), fileSize); file.Close(); // 进行Base64编码 wxString encoded = wxBase64Encode(buffer.GetData(), buffer.GetDataLen()); return encoded; } bool CPublic::gen_default_png(const wxString& path) { wxMemoryBuffer decode = wxBase64Decode(default_png); std::ofstream out(path, std::ios::binary); if (!out.is_open()) { return false; } const auto& d = decode.GetData(); auto len = decode.GetDataLen(); out.write(static_cast<const char*>(decode.GetData()), decode.GetBufSize()); out.close(); return true; } CFunInstall::CFunInstall() = default; bool CFunInstall::install(const wxString& file, const wxString& category, const wxString& ico) { fs::path full_path(file.ToStdWstring()); wxString file_name = full_path.filename().wstring(); wxString script_name = file_name + "_run.sh"; wxString script_full_path = fs::path(file.ToStdWstring()).parent_path().append(script_name.ToStdWstring()).wstring(); wxString script_content = "IyEvYmluL2Jhc2gKU0NSSVBUX0RJUj0kKGNkICIkKGRpcm5hbWUgIiQwIikiICYmIHB3ZCkKY2QgIiRTQ1JJUFRfRElSIiB8fCBl" "eGl0CmV4cG9ydCBMRF9MSUJSQVJZX1BBVEg9JExE" "X0xJQlJBUllfUEFUSDoiJFNDUklQVF9ESVIiCiIkU0NSSVBUX0RJUi9yZXBsYWNlX3N0ciIgIiRAIgo="; wxMemoryBuffer decodeData = wxBase64Decode(script_content); script_content = wxString::FromUTF8(static_cast<const char*>(decodeData.GetData()), decodeData.GetBufSize()); wxString desktop_content = "W0Rlc2t0b3AgRW50cnldCk5hbWU9cmVfbmFtZQpDb21tZW50PXJlX2Rlc2NyaWJlCkV4ZWM9cmVfc" "GF0aApJY29uPXJlX2ljb24KVGVybWluYWw9ZmFsc2UKVHlwZT1BcHBsaWNhdGlv" "bgpDYXRlZ29yaWVzPXJlX2NhdGVnb3J5Owo="; wxMemoryBuffer decodeData2 = wxBase64Decode(desktop_content); desktop_content = wxString::FromUTF8(static_cast<const char*>(decodeData2.GetData()), decodeData2.GetDataLen()); // write temp file fs::path temp(wxGetHomeDir().ToStdWstring()); temp.append(".config").append("LinuxPack"); fs::path temp_png = temp; temp_png.append("default.png"); wxString ico_path = ico; if (ico.empty() && CPublic::gen_default_png(temp_png.wstring())) { ico_path = temp_png.wstring(); } script_content.Replace("replace_str", file_name); desktop_content.Replace("re_name", file_name); desktop_content.Replace("re_describe", "default"); desktop_content.Replace("re_path", script_full_path); desktop_content.Replace("re_icon", ico_path); desktop_content.Replace("re_category", category); if (!CPublic::write_txt(script_content, script_full_path)) { return false; } wxString chmod_sh = "chmod +x " + script_full_path; wxArrayString output; wxExecute(chmod_sh, output, wxEXEC_ASYNC); fs::create_directories(temp); temp.append((file_name + ".desktop").ToStdWstring()); if (!CPublic::write_txt(desktop_content, temp.wstring())) { return false; } // purdir wxString pur_dir = "/usr/share/applications"; wxString desktop_cmd = "pkexec cp " + temp.wstring() + " " + pur_dir; output.clear(); wxExecute(desktop_cmd, output, wxEXEC_ASYNC); return true; } bool CPublic::write_txt(const wxString& content, const wxString& path) { wxTextFile file; if (wxFileName::FileExists(path)) { // 如果存在,删除文件 if (!wxRemoveFile(path)) { wxLogError(wxT("无法删除现有文件: %s"), path); return false; } } if (!file.Create(path)) { wxLogError(wxT("无法创建文件: %s"), path); return false; } if (!file.Open(path)) { wxLogError(wxT("Open File Failed: %s"), path); return false; } file.AddLine(content); file.Write(); // 写入内容 file.Close(); // 关闭文件 return true; }