////////////////////////////////////////////////////////////////////// This is only used on macOS to extract the executable from the bundle. You have to look at the plist.info file, you can't just assume whatever you find in the /MacOS folder is the executable. The initial path is the folder where info.plist resides, and the path is completed to the executable upon completion. Note, not ALL macOS
| 34 | /// executable is fed in here, it will silently just return without |
| 35 | /// modifying the path (which will be the correct behavior) |
| 36 | static bool ExactExecutableFromAppBundle(Path& app_path) { |
| 37 | std::string path = app_path.AbsolutePath(); |
| 38 | path += "/Contents/"; |
| 39 | std::string list_file = path + "Info.plist"; |
| 40 | QFile file(list_file.c_str()); |
| 41 | if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { |
| 42 | return false; |
| 43 | } |
| 44 | |
| 45 | QTextStream stream(&file); |
| 46 | |
| 47 | // Read a line at a time looking for the executable tag |
| 48 | QString line_buffer; |
| 49 | while (!stream.atEnd()) { |
| 50 | line_buffer = stream.readLine(); |
| 51 | if (line_buffer.contains("<key>CFBundleExecutable</key>")) { // Exe follows this |
| 52 | line_buffer = stream.readLine(); // <string>Qt Creator</string> |
| 53 | char* cExeName = new char[line_buffer.length()]; // Prevent buffer overrun |
| 54 | |
| 55 | QByteArray line_array = line_buffer.toUtf8(); |
| 56 | const char* pStart = strstr(line_array.constData(), "<string>"); |
| 57 | if (pStart == nullptr) return false; |
| 58 | |
| 59 | // We found it, now extract it out |
| 60 | pStart += 8; |
| 61 | int iIndex = 0; |
| 62 | while (*pStart != '<') { |
| 63 | cExeName[iIndex++] = *pStart++; |
| 64 | } |
| 65 | cExeName[iIndex] = '\0'; |
| 66 | |
| 67 | // Complete the partial path |
| 68 | path += "MacOS/"; |
| 69 | path += cExeName; |
| 70 | |
| 71 | // Return original if not found, but root if found |
| 72 | app_path = Path(path); |
| 73 | |
| 74 | delete[] cExeName; |
| 75 | break; |
| 76 | } |
| 77 | } |
| 78 | |
| 79 | file.close(); |
| 80 | |
| 81 | return true; |
| 82 | } |
| 83 | |
| 84 | DefaultPath GetDefaultExecutablePath(const std::string& executable_name) { |
| 85 | const bool is_app = ::EndsWith(executable_name, ".app"); |
no test coverage detected