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
|
// External Dependencies
|
||||||
#include <shlwapi.h> // PathRemoveFileSpecA
|
#include <shlwapi.h> // PathRemoveFileSpecA
|
||||||
#include "Tools/Logger/SHLogger.h"
|
#include "Tools/Logger/SHLogger.h"
|
||||||
|
#include "Tools/Utilities/SHExecUtilities.h"
|
||||||
|
#include "Tools/Utilities/SHStringUtilities.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -59,6 +61,10 @@ namespace SHADE
|
||||||
if (initialised)
|
if (initialised)
|
||||||
throw std::runtime_error("[DotNetRuntime] Failed to initialise as it was already initialised or was deinitialised into an invalid state.");
|
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
|
// Get the current executable directory
|
||||||
std::string runtimePath(MAX_PATH, '\0');
|
std::string runtimePath(MAX_PATH, '\0');
|
||||||
GetModuleFileNameA(nullptr, runtimePath.data(), MAX_PATH);
|
GetModuleFileNameA(nullptr, runtimePath.data(), MAX_PATH);
|
||||||
|
@ -70,7 +76,7 @@ namespace SHADE
|
||||||
if (coreClr == nullptr)
|
if (coreClr == nullptr)
|
||||||
{
|
{
|
||||||
// Construct the CoreCLR path
|
// 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";
|
coreClrPath += "\\coreclr.dll";
|
||||||
|
|
||||||
// Load the CoreCLR DLL
|
// Load the CoreCLR DLL
|
||||||
|
@ -94,7 +100,7 @@ namespace SHADE
|
||||||
// trusted system assemblies (similar to the .NET Framework GAC).
|
// trusted system assemblies (similar to the .NET Framework GAC).
|
||||||
// For this host (as with most), assemblies next to CoreCLR will
|
// For this host (as with most), assemblies next to CoreCLR will
|
||||||
// be included in the TPA list
|
// be included in the TPA list
|
||||||
std::string tpaList = buildTpaList(runtimePath);
|
std::string tpaList = buildTpaList(DOT_NET_PATH->string());
|
||||||
|
|
||||||
// Define CoreCLR properties
|
// Define CoreCLR properties
|
||||||
std::array propertyKeys =
|
std::array propertyKeys =
|
||||||
|
@ -195,4 +201,82 @@ namespace SHADE
|
||||||
throw std::runtime_error(oss.str());
|
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);
|
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