Merge branch 'rider_2021_support' of git://github.com/GoaLitiuM/FlaxEngine into GoaLitiuM-rider_2021_support

This commit is contained in:
Wojtek Figat
2021-05-28 09:49:03 +02:00

View File

@@ -10,12 +10,24 @@
#if PLATFORM_WINDOWS
#include "Engine/Core/Collections/Sorting.h"
#include "Engine/Platform/File.h"
#include "Engine/Platform/Win32/IncludeWindowsHeaders.h"
#include "Engine/Serialization/Json.h"
namespace
{
struct RiderInstallation
{
String path;
String version;
RiderInstallation(const String& path_, const String& version_)
: path(path_), version(version_)
{
}
};
bool FindRegistryKeyItems(HKEY hKey, Array<String>& results)
{
Char nameBuffer[256];
@@ -31,7 +43,7 @@ namespace
return true;
}
void SearchDirectory(Array<CodeEditor*>* output, const String& directory)
void SearchDirectory(Array<RiderInstallation*>* installations, const String& directory)
{
if (!FileSystem::DirectoryExists(directory))
return;
@@ -46,24 +58,29 @@ namespace
if (document.HasParseError())
return;
// Find version
auto versionMember = document.FindMember("version");
if (versionMember == document.MemberEnd())
return;
// Find executable file path
auto launchMember = document.FindMember("launch");
if (launchMember != document.MemberEnd() && launchMember->value.IsArray() && launchMember->value.Size() > 0)
{
auto launcherPathMember = launchMember->value[0].FindMember("launcherPath");
if (launcherPathMember != launchMember->value[0].MemberEnd())
{
auto launcherPath = launcherPathMember->value.GetText();
auto exePath = directory / launcherPath;
if (launcherPath.HasChars() && FileSystem::FileExists(exePath))
{
output->Add(New<RiderCodeEditor>(exePath));
}
}
}
if (launchMember == document.MemberEnd() || !launchMember->value.IsArray() || launchMember->value.Size() == 0)
return;
auto launcherPathMember = launchMember->value[0].FindMember("launcherPath");
if (launcherPathMember == launchMember->value[0].MemberEnd())
return;
auto launcherPath = launcherPathMember->value.GetText();
auto exePath = directory / launcherPath;
if (!launcherPath.HasChars() || !FileSystem::FileExists(exePath))
return;
installations->Add(New<RiderInstallation>(exePath, versionMember->value.GetText()));
}
void SearchRegistry(Array<CodeEditor*>* output, HKEY root, const Char* key)
void SearchRegistry(Array<RiderInstallation*>* installations, HKEY root, const Char* key, const Char* valueName = TEXT(""))
{
// Open key
HKEY keyH;
@@ -83,14 +100,14 @@ namespace
// Read subkey value
DWORD type;
DWORD cbData;
if (RegQueryValueExW(subKeyH, TEXT(""), nullptr, &type, nullptr, &cbData) != ERROR_SUCCESS || type != REG_SZ)
if (RegQueryValueExW(subKeyH, valueName, nullptr, &type, nullptr, &cbData) != ERROR_SUCCESS || type != REG_SZ)
{
RegCloseKey(subKeyH);
continue;
}
Array<Char> data;
data.Resize((int32)cbData / sizeof(Char));
if (RegQueryValueExW(subKeyH, TEXT(""), nullptr, nullptr, reinterpret_cast<LPBYTE>(data.Get()), &cbData) != ERROR_SUCCESS)
if (RegQueryValueExW(subKeyH, valueName, nullptr, nullptr, reinterpret_cast<LPBYTE>(data.Get()), &cbData) != ERROR_SUCCESS)
{
RegCloseKey(subKeyH);
continue;
@@ -98,7 +115,7 @@ namespace
// Check if it's a valid installation path
String path(data.Get(), data.Count() - 1);
SearchDirectory(output, path);
SearchDirectory(installations, path);
RegCloseKey(subKeyH);
}
@@ -108,6 +125,31 @@ namespace
}
}
bool sortInstallations(RiderInstallation* const& i1, RiderInstallation* const& i2)
{
Array<String> values1, values2;
i1->version.Split('.', values1);
i2->version.Split('.', values2);
int32 version1[3] = { 0 };
int32 version2[3] = { 0 };
StringUtils::Parse(values1[0].Get(), &version1[0]);
StringUtils::Parse(values1[1].Get(), &version1[1]);
StringUtils::Parse(values1[2].Get(), &version1[2]);
StringUtils::Parse(values2[0].Get(), &version2[0]);
StringUtils::Parse(values2[1].Get(), &version2[1]);
StringUtils::Parse(values2[2].Get(), &version2[2]);
// Compare by MAJOR.MINOR.BUILD
if (version1[0] == version2[0])
{
if (version1[1] == version2[1])
return version1[2] > version2[2];
return version1[1] > version2[1];
}
return version1[0] > version2[0];
}
#endif
RiderCodeEditor::RiderCodeEditor(const String& execPath)
@@ -119,8 +161,23 @@ RiderCodeEditor::RiderCodeEditor(const String& execPath)
void RiderCodeEditor::FindEditors(Array<CodeEditor*>* output)
{
#if PLATFORM_WINDOWS
SearchRegistry(output, HKEY_CURRENT_USER, TEXT("SOFTWARE\\WOW6432Node\\JetBrains\\JetBrains Rider"));
SearchRegistry(output, HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\WOW6432Node\\JetBrains\\JetBrains Rider"));
Array<RiderInstallation*> installations;
// For versions 2021 or later
SearchRegistry(&installations, HKEY_CURRENT_USER, TEXT("SOFTWARE\\JetBrains\\Rider"), TEXT("InstallDir"));
// For versions 2020 or earlier
SearchRegistry(&installations, HKEY_CURRENT_USER, TEXT("SOFTWARE\\WOW6432Node\\JetBrains\\JetBrains Rider"));
SearchRegistry(&installations, HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\WOW6432Node\\JetBrains\\JetBrains Rider"));
// Sort found installations by version number
Sorting::QuickSort(installations.Get(), installations.Count(), &sortInstallations);
for (RiderInstallation* installation : installations)
{
output->Add(New<RiderCodeEditor>(installation->path));
Delete(installation);
}
#endif
}