Add support for Rider 2021, use latest detected version of Rider
Handles additional registry location where installation paths are stored for Rider 2021. The detected installations are now sorted by version, so the latest detected version is always used when opening the scripts project.
This commit is contained in:
@@ -10,12 +10,24 @@
|
|||||||
|
|
||||||
#if PLATFORM_WINDOWS
|
#if PLATFORM_WINDOWS
|
||||||
|
|
||||||
|
#include "Engine/Core/Collections/Sorting.h"
|
||||||
#include "Engine/Platform/File.h"
|
#include "Engine/Platform/File.h"
|
||||||
#include "Engine/Platform/Win32/IncludeWindowsHeaders.h"
|
#include "Engine/Platform/Win32/IncludeWindowsHeaders.h"
|
||||||
#include "Engine/Serialization/Json.h"
|
#include "Engine/Serialization/Json.h"
|
||||||
|
|
||||||
namespace
|
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)
|
bool FindRegistryKeyItems(HKEY hKey, Array<String>& results)
|
||||||
{
|
{
|
||||||
Char nameBuffer[256];
|
Char nameBuffer[256];
|
||||||
@@ -31,7 +43,7 @@ namespace
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SearchDirectory(Array<CodeEditor*>* output, const String& directory)
|
void SearchDirectory(Array<RiderInstallation*>* installations, const String& directory)
|
||||||
{
|
{
|
||||||
if (!FileSystem::DirectoryExists(directory))
|
if (!FileSystem::DirectoryExists(directory))
|
||||||
return;
|
return;
|
||||||
@@ -46,24 +58,29 @@ namespace
|
|||||||
if (document.HasParseError())
|
if (document.HasParseError())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Find version
|
||||||
|
auto versionMember = document.FindMember("version");
|
||||||
|
if (versionMember == document.MemberEnd())
|
||||||
|
return;
|
||||||
|
|
||||||
// Find executable file path
|
// Find executable file path
|
||||||
auto launchMember = document.FindMember("launch");
|
auto launchMember = document.FindMember("launch");
|
||||||
if (launchMember != document.MemberEnd() && launchMember->value.IsArray() && launchMember->value.Size() > 0)
|
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())
|
auto launcherPathMember = launchMember->value[0].FindMember("launcherPath");
|
||||||
{
|
if (launcherPathMember == launchMember->value[0].MemberEnd())
|
||||||
auto launcherPath = launcherPathMember->value.GetText();
|
return;
|
||||||
auto exePath = directory / launcherPath;
|
|
||||||
if (launcherPath.HasChars() && FileSystem::FileExists(exePath))
|
auto launcherPath = launcherPathMember->value.GetText();
|
||||||
{
|
auto exePath = directory / launcherPath;
|
||||||
output->Add(New<RiderCodeEditor>(exePath));
|
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
|
// Open key
|
||||||
HKEY keyH;
|
HKEY keyH;
|
||||||
@@ -83,14 +100,14 @@ namespace
|
|||||||
// Read subkey value
|
// Read subkey value
|
||||||
DWORD type;
|
DWORD type;
|
||||||
DWORD cbData;
|
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);
|
RegCloseKey(subKeyH);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Array<Char> data;
|
Array<Char> data;
|
||||||
data.Resize((int32)cbData / sizeof(Char));
|
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);
|
RegCloseKey(subKeyH);
|
||||||
continue;
|
continue;
|
||||||
@@ -98,7 +115,7 @@ namespace
|
|||||||
|
|
||||||
// Check if it's a valid installation path
|
// Check if it's a valid installation path
|
||||||
String path(data.Get(), data.Count() - 1);
|
String path(data.Get(), data.Count() - 1);
|
||||||
SearchDirectory(output, path);
|
SearchDirectory(installations, path);
|
||||||
|
|
||||||
RegCloseKey(subKeyH);
|
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
|
#endif
|
||||||
|
|
||||||
RiderCodeEditor::RiderCodeEditor(const String& execPath)
|
RiderCodeEditor::RiderCodeEditor(const String& execPath)
|
||||||
@@ -119,8 +161,23 @@ RiderCodeEditor::RiderCodeEditor(const String& execPath)
|
|||||||
void RiderCodeEditor::FindEditors(Array<CodeEditor*>* output)
|
void RiderCodeEditor::FindEditors(Array<CodeEditor*>* output)
|
||||||
{
|
{
|
||||||
#if PLATFORM_WINDOWS
|
#if PLATFORM_WINDOWS
|
||||||
SearchRegistry(output, HKEY_CURRENT_USER, TEXT("SOFTWARE\\WOW6432Node\\JetBrains\\JetBrains Rider"));
|
Array<RiderInstallation*> installations;
|
||||||
SearchRegistry(output, HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\WOW6432Node\\JetBrains\\JetBrains Rider"));
|
|
||||||
|
// 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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user