Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add hostfxr_get_dotnet_environment_info API #48097

Merged
merged 12 commits into from
Feb 13, 2021
18 changes: 16 additions & 2 deletions src/installer/corehost/cli/fxr/framework_info.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,17 @@ bool compare_by_name_and_version(const framework_info &a, const framework_info &
return false;
}

return a.version < b.version;
if (a.version < b.version)
{
return true;
}

if (a.version == b.version)
{
return a.hive_depth > b.hive_depth;
}

return false;
}

/*static*/ void framework_info::get_all_framework_infos(
Expand All @@ -30,6 +40,8 @@ bool compare_by_name_and_version(const framework_info &a, const framework_info &
std::vector<pal::string_t> hive_dir;
get_framework_and_sdk_locations(own_dir, &hive_dir);

int32_t hive_depth = 0;

for (pal::string_t dir : hive_dir)
{
auto fx_shared_dir = dir;
Expand Down Expand Up @@ -68,13 +80,15 @@ bool compare_by_name_and_version(const framework_info &a, const framework_info &
{
trace::verbose(_X("Found FX version [%s]"), ver.c_str());

framework_info info(fx_name, fx_dir, parsed);
framework_info info(fx_name, fx_dir, parsed, hive_depth);
framework_infos->push_back(info);
}
}
}
}
}

hive_depth++;
}

std::sort(framework_infos->begin(), framework_infos->end(), compare_by_name_and_version);
Expand Down
6 changes: 4 additions & 2 deletions src/installer/corehost/cli/fxr/framework_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@

struct framework_info
{
framework_info(pal::string_t name, pal::string_t path, fx_ver_t version)
framework_info(pal::string_t name, pal::string_t path, fx_ver_t version, int32_t hive_depth)
: name(name)
, path(path)
, version(version) { }
, version(version)
, hive_depth(hive_depth) { }

static void get_all_framework_infos(
const pal::string_t& own_dir,
Expand All @@ -24,6 +25,7 @@ struct framework_info
pal::string_t name;
pal::string_t path;
fx_ver_t version;
int32_t hive_depth;
};

#endif // __FRAMEWORK_INFO_H_
133 changes: 133 additions & 0 deletions src/installer/corehost/cli/fxr/hostfxr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "hostfxr.h"
#include "host_context.h"
#include "bundle/info.h"
#include <framework_info.h>

namespace
{
Expand Down Expand Up @@ -330,6 +331,138 @@ SHARED_API int32_t HOSTFXR_CALLTYPE hostfxr_get_available_sdks(
return StatusCode::Success;
}

//
// Returns available SDKs and frameworks.
//
// Resolves the existing SDKs and frameworks from a dotnet root directory (if
// any), or the global default location. If multi-level lookup is enabled and
// the dotnet root location is different than the global location, the SDKs and
// frameworks will be enumerated from both locations.
//
// The SDKs are sorted in ascending order by version, multi-level lookup
// locations are put before private ones.
//
// The frameworks are sorted in ascending order by name followed by version,
// multi-level lookup locations are put before private ones.
//
// Parameters:
// dotnet_root
// The path to a directory containing a dotnet executable.
//
// reserved
// Reserved for future parameters.
//
// result
// Callback invoke to return the list of SDKs and frameworks.
// Structs and their elements are valid for the duration of the call.
//
// result_context
// Additional context passed to the result callback.
//
// Return value:
// 0 on success, otherwise failure.
//
// String encoding:
// Windows - UTF-16 (pal::char_t is 2 byte wchar_t)
// Unix - UTF-8 (pal::char_t is 1 byte char)
//
SHARED_API int32_t HOSTFXR_CALLTYPE hostfxr_get_dotnet_environment_info(
const pal::char_t* dotnet_root,
void* reserved,
hostfxr_get_dotnet_environment_info_result_fn result,
void* result_context)
{
if (result == nullptr)
{
trace::error(_X("hostfxr_get_dotnet_environment_info received an invalid argument: result should not be null."));
return StatusCode::InvalidArgFailure;
}
mateoatr marked this conversation as resolved.
Show resolved Hide resolved

if (reserved != nullptr)
{
trace::error(_X("hostfxr_get_dotnet_environment_info received an invalid argument: reserved should be null."));
return StatusCode::InvalidArgFailure;
}

pal::string_t dotnet_dir;
if (dotnet_root == nullptr)
{
if (pal::get_dotnet_self_registered_dir(&dotnet_dir) || pal::get_default_installation_dir(&dotnet_dir))
{
trace::info(_X("Using global installation location [%s]."), dotnet_dir.c_str());
}
else
{
trace::info(_X("No default dotnet installation could be obtained."));
}
}
else
{
dotnet_dir = dotnet_root;
}

std::vector<sdk_info> sdk_infos;
sdk_info::get_all_sdk_infos(dotnet_dir, &sdk_infos);

std::vector<hostfxr_dotnet_environment_sdk_info> environment_sdk_infos;
std::vector<pal::string_t> sdk_versions;
if (!sdk_infos.empty())
{
environment_sdk_infos.reserve(sdk_infos.size());
sdk_versions.reserve(sdk_infos.size());
for (const sdk_info& info : sdk_infos)
{
sdk_versions.push_back(info.version.as_str());
hostfxr_dotnet_environment_sdk_info sdk
{
sizeof(hostfxr_dotnet_environment_sdk_info),
sdk_versions.back().c_str(),
info.full_path.c_str()
};

environment_sdk_infos.push_back(sdk);
}
}

std::vector<framework_info> framework_infos;
framework_info::get_all_framework_infos(dotnet_dir, _X(""), &framework_infos);

std::vector<hostfxr_dotnet_environment_framework_info> environment_framework_infos;
std::vector<pal::string_t> framework_versions;
if (!framework_infos.empty())
{
environment_framework_infos.reserve(framework_infos.size());
framework_versions.reserve(framework_infos.size());
for (const framework_info& info : framework_infos)
{
framework_versions.push_back(info.version.as_str());
hostfxr_dotnet_environment_framework_info fw
{
sizeof(hostfxr_dotnet_environment_framework_info),
info.name.c_str(),
framework_versions.back().c_str(),
info.path.c_str()
};

environment_framework_infos.push_back(fw);
}
}

const hostfxr_dotnet_environment_info environment_info
{
sizeof(hostfxr_dotnet_environment_info),
_STRINGIFY(HOST_FXR_PKG_VER),
_STRINGIFY(REPO_COMMIT_HASH),
environment_sdk_infos.size(),
(environment_sdk_infos.empty()) ? nullptr : &environment_sdk_infos[0],
environment_framework_infos.size(),
(environment_framework_infos.empty()) ? nullptr : &environment_framework_infos[0]
};

result(&environment_info, result_context);
return StatusCode::Success;
}

//
// Returns the native directories of the runtime based upon
// the specified app.
Expand Down
1 change: 1 addition & 0 deletions src/installer/corehost/cli/fxr/standalone/hostfxr.def
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ EXPORTS
hostfxr_resolve_sdk
hostfxr_resolve_sdk2
hostfxr_get_available_sdks
hostfxr_get_dotnet_environment_info
hostfxr_get_native_search_directories
hostfxr_set_error_writer
hostfxr_initialize_for_dotnet_command_line
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ hostfxr_main
hostfxr_resolve_sdk
hostfxr_resolve_sdk2
hostfxr_get_available_sdks
hostfxr_get_dotnet_environment_info
hostfxr_get_native_search_directories
hostfxr_set_error_writer
hostfxr_initialize_for_dotnet_command_line
Expand Down
33 changes: 33 additions & 0 deletions src/installer/corehost/cli/hostfxr.h
Original file line number Diff line number Diff line change
Expand Up @@ -285,4 +285,37 @@ typedef int32_t(HOSTFXR_CALLTYPE *hostfxr_get_runtime_delegate_fn)(
//
typedef int32_t(HOSTFXR_CALLTYPE *hostfxr_close_fn)(const hostfxr_handle host_context_handle);

struct hostfxr_dotnet_environment_sdk_info
{
size_t size;
const char_t* version;
const char_t* path;
};

typedef void(HOSTFXR_CALLTYPE* hostfxr_get_dotnet_environment_info_result_fn)(
const struct hostfxr_dotnet_environment_info* info,
void* result_context);

struct hostfxr_dotnet_environment_framework_info
{
size_t size;
const char_t* name;
const char_t* version;
const char_t* path;
};

struct hostfxr_dotnet_environment_info
{
size_t size;

const char_t* hostfxr_version;
const char_t* hostfxr_commit_hash;

int32_t sdk_count;
const hostfxr_dotnet_environment_sdk_info* sdks;

int32_t framework_count;
const hostfxr_dotnet_environment_framework_info* frameworks;
};

#endif //__HOSTFXR_H__
Loading