diff --git a/es-app/src/FileData.cpp b/es-app/src/FileData.cpp index 0fea52c22..aff94a8ce 100644 --- a/es-app/src/FileData.cpp +++ b/es-app/src/FileData.cpp @@ -1064,6 +1064,9 @@ std::string FileData::findEmulatorPath(std::string& command) // Method 1, emulator binary is defined using find rules: + #if defined(_WIN64) + std::vector emulatorWinRegistryPaths; + #endif std::vector emulatorSystemPaths; std::vector emulatorStaticPaths; std::string emulatorEntry; @@ -1076,6 +1079,10 @@ std::string FileData::findEmulatorPath(std::string& command) } if (emulatorEntry != "") { + #if defined(_WIN64) + emulatorWinRegistryPaths = + SystemData::sFindRules.get()->mEmulators[emulatorEntry].winRegistryPaths; + #endif emulatorSystemPaths = SystemData::sFindRules.get()->mEmulators[emulatorEntry].systemPaths; emulatorStaticPaths = SystemData::sFindRules.get()->mEmulators[emulatorEntry].staticPaths; } @@ -1084,6 +1091,66 @@ std::string FileData::findEmulatorPath(std::string& command) if (emulatorEntry != "" && emulatorSystemPaths.empty() && emulatorStaticPaths.empty()) return "NO EMULATOR RULE: " + emulatorEntry; + #if defined(_WIN64) + for (std::string path : emulatorWinRegistryPaths) { + // Search for the emulator using the App Paths keys in the Windows Registry. + std::string registryKeyPath = + "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\" + path; + + HKEY registryKey; + LSTATUS keyStatus = -1; + LSTATUS pathStatus = -1; + char registryPath[1024] {}; + DWORD pathSize = 1024; + + // First look in HKEY_CURRENT_USER. + keyStatus = RegOpenKeyEx( + HKEY_CURRENT_USER, + registryKeyPath.c_str(), + 0, + KEY_QUERY_VALUE, + ®istryKey); + + // If not found, then try in HKEY_LOCAL_MACHINE. + if (keyStatus != ERROR_SUCCESS) { + keyStatus = RegOpenKeyEx( + HKEY_LOCAL_MACHINE, + registryKeyPath.c_str(), + 0, + KEY_QUERY_VALUE, + ®istryKey); + } + + // If the key exists, then try to retrieve the value. + if (keyStatus == ERROR_SUCCESS) { + pathStatus = RegGetValue( + registryKey, + nullptr, + nullptr, + RRF_RT_REG_SZ, + nullptr, + ®istryPath, + &pathSize); + } + else { + RegCloseKey(registryKey); + continue; + } + + // That a value was found does not guarantee that the emulator binary actually exists, + // so check for that as well. + if (pathStatus == ERROR_SUCCESS) { + if (Utils::FileSystem::isRegularFile(registryPath) || + Utils::FileSystem::isSymlink(registryPath)) { + command.replace(0, endPos + 1, registryPath); + RegCloseKey(registryKey); + return registryPath; + } + } + RegCloseKey(registryKey); + } + #endif + for (std::string path : emulatorSystemPaths) { #if defined(_WIN64) std::wstring pathWide = Utils::String::stringToWideString(path); diff --git a/es-app/src/SystemData.cpp b/es-app/src/SystemData.cpp index 118981b67..bb415815b 100644 --- a/es-app/src/SystemData.cpp +++ b/es-app/src/SystemData.cpp @@ -115,7 +115,12 @@ void FindRules::loadFindRules() emulatorName << "\", skipping entry"; continue; } + #if defined(_WIN64) + if (ruleType != "winregistrypath" && ruleType != "systempath" && + ruleType != "staticpath") { + #else if (ruleType != "systempath" && ruleType != "staticpath") { + #endif LOG(LogWarning) << "Found invalid rule type \"" << ruleType << "\" for emulator \"" << emulatorName << "\", skipping entry"; continue; @@ -127,11 +132,18 @@ void FindRules::loadFindRules() emulatorRules.systemPaths.push_back(entryValue); else if (ruleType == "staticpath") emulatorRules.staticPaths.push_back(entryValue); + #if defined(_WIN64) + else if (ruleType == "winregistrypath") + emulatorRules.winRegistryPaths.push_back(entryValue); + #endif } } mEmulators[emulatorName] = emulatorRules; emulatorRules.systemPaths.clear(); emulatorRules.staticPaths.clear(); + #if defined(_WIN64) + emulatorRules.winRegistryPaths.clear(); + #endif } for (pugi::xml_node core = ruleList.child("core"); core; diff --git a/es-app/src/SystemData.h b/es-app/src/SystemData.h index 9d89946b2..8d138769e 100644 --- a/es-app/src/SystemData.h +++ b/es-app/src/SystemData.h @@ -41,6 +41,9 @@ public: private: struct EmulatorRules { + #if defined(_WIN64) + std::vector winRegistryPaths; + #endif std::vector systemPaths; std::vector staticPaths; }; diff --git a/resources/systems/windows/es_find_rules.xml b/resources/systems/windows/es_find_rules.xml index 657d47602..f0a9e0150 100644 --- a/resources/systems/windows/es_find_rules.xml +++ b/resources/systems/windows/es_find_rules.xml @@ -1,15 +1,20 @@ - + + + + retroarch.exe + retroarch.exe - + C:\RetroArch-Win64\retroarch.exe C:\RetroArch\retroarch.exe + ~\AppData\Roaming\RetroArch\retroarch.exe C:\Program Files\RetroArch-Win64\retroarch.exe C:\Program Files\RetroArch\retroarch.exe C:\Program Files (x86)\RetroArch-Win64\retroarch.exe @@ -20,7 +25,7 @@ - + yuzu.exe