Modified dotnet runtime system to use the user's installed dotnet runtime instead.
This commit is contained in:
parent
0f7d86543f
commit
94fa84bf78
|
@ -21,6 +21,8 @@ of DigiPen Institute of Technology is prohibited.
|
|||
// External Dependencies
|
||||
#include <shlwapi.h> // PathRemoveFileSpecA
|
||||
#include "Tools/Logger/SHLogger.h"
|
||||
#include "Tools/Utilities/SHExecUtilities.h"
|
||||
#include "Tools/Utilities/SHStringUtilities.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
@ -59,6 +61,10 @@ namespace SHADE
|
|||
if (initialised)
|
||||
throw std::runtime_error("[DotNetRuntime] Failed to initialise as it was already initialised or was deinitialised into an invalid state.");
|
||||
|
||||
const auto DOT_NET_PATH = getDotNetRuntimePath();
|
||||
if (!DOT_NET_PATH)
|
||||
throw std::runtime_error("[DotNetRuntime] .NET Runtime installation is missing.");
|
||||
|
||||
// Get the current executable directory
|
||||
std::string runtimePath(MAX_PATH, '\0');
|
||||
GetModuleFileNameA(nullptr, runtimePath.data(), MAX_PATH);
|
||||
|
@ -70,7 +76,7 @@ namespace SHADE
|
|||
if (coreClr == nullptr)
|
||||
{
|
||||
// Construct the CoreCLR path
|
||||
std::string coreClrPath(runtimePath); // Works
|
||||
std::string coreClrPath("C:\\Program Files\\dotnet\\shared\\Microsoft.NETCore.App\\5.0.17"); // Works
|
||||
coreClrPath += "\\coreclr.dll";
|
||||
|
||||
// Load the CoreCLR DLL
|
||||
|
@ -94,7 +100,7 @@ namespace SHADE
|
|||
// trusted system assemblies (similar to the .NET Framework GAC).
|
||||
// For this host (as with most), assemblies next to CoreCLR will
|
||||
// be included in the TPA list
|
||||
std::string tpaList = buildTpaList(runtimePath);
|
||||
std::string tpaList = buildTpaList(DOT_NET_PATH->string());
|
||||
|
||||
// Define CoreCLR properties
|
||||
std::array propertyKeys =
|
||||
|
@ -195,4 +201,82 @@ namespace SHADE
|
|||
throw std::runtime_error(oss.str());
|
||||
}
|
||||
}
|
||||
std::optional<std::filesystem::path> SHDotNetRuntime::getDotNetRuntimePath()
|
||||
{
|
||||
// Check if dotnet is installed
|
||||
const auto DOT_NET_PATH = std::filesystem::path(L"C:\\Program Files\\dotnet\\dotnet.exe");
|
||||
if (!std::filesystem::exists(DOT_NET_PATH))
|
||||
return {};
|
||||
|
||||
// Execute dotnet to search for
|
||||
const auto RUNTIME_SEARCH = SHExecUtilties::ExecBlockingProcess(DOT_NET_PATH.wstring(), L" --list-runtimes", true, false);
|
||||
if (RUNTIME_SEARCH.Code != 0)
|
||||
return {};
|
||||
|
||||
// Remove all except Microsoft.NETCore.App entries
|
||||
auto runtimeEntries = SHStringUtilities::Split(RUNTIME_SEARCH.StdOutput, L'\n');
|
||||
std::erase_if(runtimeEntries, [](const std::wstring& str)
|
||||
{
|
||||
return str.find(L".NETCore.App") == std::wstring::npos;
|
||||
});
|
||||
|
||||
// Early exit if there is none
|
||||
if (runtimeEntries.empty())
|
||||
return {};
|
||||
|
||||
// Select the highest version
|
||||
std::wstring highestVersion;
|
||||
int major = 0; int minor = 0; int revision = 0;
|
||||
for (const auto& entry : runtimeEntries)
|
||||
{
|
||||
auto start = entry.find_first_of(L"1234567890");
|
||||
auto end = entry.find_last_of(L"1234567890");
|
||||
|
||||
// No version string found
|
||||
if (start == std::wstring::npos)
|
||||
continue;
|
||||
|
||||
// Grab the version string and tokenize it to parts
|
||||
const std::wstring VER_STR = entry.substr(start, end - start + 1);
|
||||
const auto VERSION_TOKENS = SHStringUtilities::Split(VER_STR, L'.');
|
||||
|
||||
// Invalid version string
|
||||
if (VERSION_TOKENS.size() < 3)
|
||||
continue;
|
||||
|
||||
// Get version strings
|
||||
const auto thisMajor = stoi(VERSION_TOKENS[0]);
|
||||
const auto thisMinor = stoi(VERSION_TOKENS[1]);
|
||||
const auto thisRevision = stoi(VERSION_TOKENS[2]);
|
||||
|
||||
if (major > thisRevision)
|
||||
continue;
|
||||
if (minor > thisMinor)
|
||||
continue;
|
||||
if (revision > thisRevision)
|
||||
continue;
|
||||
|
||||
major = thisMajor;
|
||||
minor = thisMinor;
|
||||
revision = thisRevision;
|
||||
highestVersion = VER_STR;
|
||||
}
|
||||
|
||||
// No suitable version found
|
||||
if (highestVersion.empty())
|
||||
return {};
|
||||
|
||||
// Extract path string
|
||||
const std::wstring& ENTRY = runtimeEntries[0];
|
||||
const auto START = ENTRY.find_first_of(L'[');
|
||||
const auto END = ENTRY.find_last_of(L']');
|
||||
// - Can't extract string
|
||||
if (START == std::wstring::npos || END == std::wstring::npos)
|
||||
return {};
|
||||
// - Extract string
|
||||
const std::wstring DIR_PATH = ENTRY.substr(START + 1, END - START - 1);
|
||||
|
||||
// Form resulting path based on found version
|
||||
return std::filesystem::path(DIR_PATH) / highestVersion;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -201,6 +201,19 @@ namespace SHADE
|
|||
*/
|
||||
/***********************************************************************************/
|
||||
static void throwIfFailed(const std::string& errMsg, int resultCode);
|
||||
/***********************************************************************************/
|
||||
/*!
|
||||
|
||||
\brief
|
||||
Searches for the dotnet runtime binary folder and returns it if it exists.
|
||||
If multiple versions are present, the latest version will be returned.
|
||||
|
||||
\return
|
||||
The path to the dotnet runtime binary folder. Null if none was found.
|
||||
|
||||
*/
|
||||
/***********************************************************************************/
|
||||
static std::optional<std::filesystem::path> getDotNetRuntimePath();
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue