return rid;
}
-bool get_env_shared_store_dirs(std::vector<pal::string_t>* dirs, const pal::string_t& arch, const pal::string_t& tfm)
-{
- pal::string_t path;
- if (!pal::getenv(_X("DOTNET_SHARED_STORE"), &path))
- {
- return false;
- }
-
- pal::string_t tok;
- pal::stringstream_t ss(path);
- while (std::getline(ss, tok, PATH_SEPARATOR))
- {
- if (pal::realpath(&tok))
- {
- append_path(&tok, arch.c_str());
- append_path(&tok, tfm.c_str());
- dirs->push_back(tok);
- }
- }
- return true;
-}
-
-bool get_global_shared_store_dirs(std::vector<pal::string_t>* dirs, const pal::string_t& arch, const pal::string_t& tfm)
-{
- std::vector<pal::string_t> global_dirs;
- if (!pal::get_global_dotnet_dirs(&global_dirs))
- {
- return false;
- }
-
- for (pal::string_t dir : global_dirs)
- {
- append_path(&dir, RUNTIME_STORE_DIRECTORY_NAME);
- append_path(&dir, arch.c_str());
- append_path(&dir, tfm.c_str());
- dirs->push_back(dir);
- }
- return true;
-}
-
/**
* Multilevel Lookup is enabled by default
* It can be disabled by setting DOTNET_MULTILEVEL_LOOKUP env var to a value that is not 1
#define INSTALL_NET_ERROR_MESSAGE _X("You must install .NET to run this application.")
#define INSTALL_NET_DESKTOP_ERROR_MESSAGE _X("You must install .NET Desktop Runtime to run this application.")
-#define RUNTIME_STORE_DIRECTORY_NAME _X("store")
-
#define DOTNET_ROOT_ENV_VAR _X("DOTNET_ROOT")
bool ends_with(const pal::string_t& value, const pal::string_t& suffix, bool match_case);
const pal::char_t* get_current_arch_name();
pal::string_t get_current_runtime_id(bool use_fallback);
-bool get_env_shared_store_dirs(std::vector<pal::string_t>* dirs, const pal::string_t& arch, const pal::string_t& tfm);
-bool get_global_shared_store_dirs(std::vector<pal::string_t>* dirs, const pal::string_t& arch, const pal::string_t& tfm);
bool multilevel_lookup_enabled();
void get_framework_and_sdk_locations(const pal::string_t& dotnet_dir, const bool disable_multilevel_lookup, std::vector<pal::string_t>* locations);
bool get_file_path_from_env(const pal::char_t* env_key, pal::string_t* recv);
arguments_t::arguments_t()
: host_mode(host_mode_t::invalid)
- , host_path(_X(""))
, app_root(_X(""))
, deps_path(_X(""))
- , core_servicing(_X(""))
, managed_application(_X(""))
, app_argc(0)
, app_argv(nullptr)
{
}
-/**
- *
- * Setup the shared store directories.
- *
- * o %DOTNET_SHARED_STORE% -- multiple delimited paths
- * o dotnet.exe relative shared store\<arch>\<tfm>
- * o Global location
- * Windows: global default location (Program Files) or globally registered location (registry) + store\<arch>\<tfm>
- * Linux/macOS: none (no global locations are considered)
- */
-void setup_shared_store_paths(const pal::string_t& tfm, host_mode_t host_mode,const pal::string_t& own_dir, arguments_t* args)
-{
- if (tfm.empty())
- {
- // Old (MNA < 1.1.*) "runtimeconfig.json" files do not contain TFM property.
- return;
- }
-
- // Environment variable DOTNET_SHARED_STORE
- (void) get_env_shared_store_dirs(&args->env_shared_store, get_current_arch_name(), tfm);
-
- // "dotnet.exe" relative shared store folder
- if (host_mode == host_mode_t::muxer)
- {
- args->dotnet_shared_store = own_dir;
- append_path(&args->dotnet_shared_store, RUNTIME_STORE_DIRECTORY_NAME);
- append_path(&args->dotnet_shared_store, get_current_arch_name());
- append_path(&args->dotnet_shared_store, tfm.c_str());
- }
-
- // Global shared store dir
- bool multilevel_lookup = multilevel_lookup_enabled();
- if (multilevel_lookup)
- {
- get_global_shared_store_dirs(&args->global_shared_stores, get_current_arch_name(), tfm);
- }
-}
-
bool parse_arguments(
const hostpolicy_init_t& init,
const int argc, const pal::char_t* argv[],
bool success = init_arguments(
managed_application_path,
- init.host_info,
- init.tfm,
init.host_mode,
- init.additional_deps_serialized,
init.deps_file,
- init.probe_paths,
/* init_from_file_system */ false,
args);
if (success)
bool init_arguments(
const pal::string_t& managed_application_path,
- const host_startup_info_t& host_info,
- const pal::string_t& tfm,
host_mode_t host_mode,
- const pal::string_t& additional_deps_serialized,
const pal::string_t& deps_file,
- const std::vector<pal::string_t>& probe_paths,
bool init_from_file_system,
arguments_t& args)
{
args.host_mode = host_mode;
- args.host_path = host_info.host_path;
- args.additional_deps_serialized = additional_deps_serialized;
// Components are never loaded from the bundle, the managed_application_path always means a file system path for a component case.
if (!set_root_from_app(managed_application_path, /* file_system_lookup_only */ init_from_file_system, args))
args.app_root = get_directory(args.deps_path);
}
- for (const auto& probe : probe_paths)
- {
- args.probe_paths.push_back(probe);
- }
-
if (args.deps_path.empty())
{
args.deps_path = get_deps_from_app_binary(args.app_root, args.managed_application);
}
- pal::get_default_servicing_directory(&args.core_servicing);
-
- setup_shared_store_paths(tfm, host_mode, get_directory(args.host_path), &args);
-
return true;
}
struct arguments_t
{
host_mode_t host_mode;
- pal::string_t host_path;
pal::string_t app_root;
pal::string_t deps_path;
- pal::string_t core_servicing;
- std::vector<pal::string_t> probe_paths;
pal::string_t managed_application;
- std::vector<pal::string_t> global_shared_stores;
- pal::string_t dotnet_shared_store;
- std::vector<pal::string_t> env_shared_store;
- pal::string_t additional_deps_serialized;
int app_argc;
const pal::char_t** app_argv;
{
if (trace::is_enabled())
{
- trace::verbose(_X("-- arguments_t: host_path='%s' app_root='%s' deps='%s' core_svc='%s' mgd_app='%s'"),
- host_path.c_str(), app_root.c_str(), deps_path.c_str(), core_servicing.c_str(), managed_application.c_str());
- for (const auto& probe : probe_paths)
- {
- trace::verbose(_X("-- arguments_t: probe dir: '%s'"), probe.c_str());
- }
- for (const auto& shared : env_shared_store)
- {
- trace::verbose(_X("-- arguments_t: env shared store: '%s'"), shared.c_str());
- }
- trace::verbose(_X("-- arguments_t: dotnet shared store: '%s'"), dotnet_shared_store.c_str());
- for (const auto& global_shared : global_shared_stores)
- {
- trace::verbose(_X("-- arguments_t: global shared store: '%s'"), global_shared.c_str());
- }
+ trace::verbose(_X("-- arguments_t: app_root='%s' deps='%s' mgd_app='%s'"),
+ app_root.c_str(), deps_path.c_str(), managed_application.c_str());
}
}
};
arguments_t& arg);
bool init_arguments(
const pal::string_t& managed_application_path,
- const host_startup_info_t& host_info,
- const pal::string_t& tfm,
host_mode_t host_mode,
- const pal::string_t& additional_deps_serialized,
const pal::string_t& deps_file,
- const std::vector<pal::string_t>& probe_paths,
bool init_from_file_system,
arguments_t& args);
#include "deps_entry.h"
#include "deps_format.h"
#include "deps_resolver.h"
+#include "shared_store.h"
#include <utils.h>
#include <fx_ver.h>
}
} // end of anonymous namespace
-
void deps_resolver_t::setup_shared_store_probes(
- const arguments_t& args)
+ const std::vector<pal::string_t>& shared_stores)
{
- for (const auto& shared : args.env_shared_store)
+ for (const pal::string_t& shared : shared_stores)
{
if (pal::directory_exists(shared))
{
- // Shared Store probe: DOTNET_SHARED_STORE environment variable
m_probes.push_back(probe_config_t::lookup(shared));
m_needs_file_existence_checks = true;
}
}
-
- if (pal::directory_exists(args.dotnet_shared_store))
- {
- // Path relative to the location of "dotnet.exe" if it's being used to run the app
- m_probes.push_back(probe_config_t::lookup(args.dotnet_shared_store));
- m_needs_file_existence_checks = true;
- }
-
- for (const auto& global_shared : args.global_shared_stores)
- {
- if (global_shared != args.dotnet_shared_store && pal::directory_exists(global_shared))
- {
- // Global store probe: the global location
- m_probes.push_back(probe_config_t::lookup(global_shared));
- m_needs_file_existence_checks = true;
- }
- }
}
pal::string_t deps_resolver_t::get_lookup_probe_directories()
}
void deps_resolver_t::setup_probe_config(
- const arguments_t& args)
+ const std::vector<pal::string_t>& shared_stores,
+ const std::vector<pal::string_t>& additional_probe_paths)
{
- if (pal::directory_exists(args.core_servicing))
+ if (pal::directory_exists(m_core_servicing))
{
- pal::string_t ext_ni = args.core_servicing;
+ pal::string_t ext_ni = m_core_servicing;
append_path(&ext_ni, get_current_arch_name());
if (pal::directory_exists(ext_ni))
{
}
// Servicing normal probe.
- pal::string_t ext_pkgs = args.core_servicing;
+ pal::string_t ext_pkgs = m_core_servicing;
append_path(&ext_pkgs, _X("pkgs"));
m_probes.push_back(probe_config_t::svc(ext_pkgs));
}
}
- setup_shared_store_probes(args);
+ setup_shared_store_probes(shared_stores);
- if (!args.probe_paths.empty())
+ if (!additional_probe_paths.empty())
{
- for (const auto& probe : args.probe_paths)
+ for (const auto& probe : additional_probe_paths)
{
// Additional paths
m_probes.push_back(probe_config_t::lookup(probe));
if (trace::is_enabled())
{
- trace::verbose(_X("-- Listing probe configurations..."));
+ trace::verbose(_X("-- Probe configurations:"));
for (const auto& pc : m_probes)
{
pc.print();
}
}
-void deps_resolver_t::resolve_additional_deps(const pal::string_t& additional_deps_serialized, const deps_json_t::rid_fallback_graph_t* rid_fallback_graph)
+void deps_resolver_t::resolve_additional_deps(const pal::char_t* additional_deps_serialized, const deps_json_t::rid_fallback_graph_t* rid_fallback_graph)
{
if (!m_is_framework_dependent
|| m_host_mode == host_mode_t::libhost)
return;
}
- if (additional_deps_serialized.empty())
+ if (additional_deps_serialized == nullptr || pal::strlen(additional_deps_serialized) == 0)
{
return;
}
deps_resolver_t(
const arguments_t& args,
const fx_definition_vector_t& fx_definitions,
+ const pal::char_t* additional_deps_serialized,
+ const std::vector<pal::string_t>& shared_stores,
+ const std::vector<pal::string_t>& additional_probe_paths,
const deps_json_t::rid_fallback_graph_t* root_framework_rid_fallback_graph,
bool is_framework_dependent)
: m_fx_definitions(fx_definitions)
, m_app_dir(args.app_root)
, m_host_mode(args.host_mode)
, m_managed_app(args.managed_application)
- , m_core_servicing(args.core_servicing)
, m_is_framework_dependent(is_framework_dependent)
, m_needs_file_existence_checks(false)
{
m_fx_deps.resize(m_fx_definitions.size());
+ pal::get_default_servicing_directory(&m_core_servicing);
// Process from lowest (root) to highest (app) framework.
// If we weren't explicitly given a rid fallback graph, that of
}
}
- resolve_additional_deps(args.additional_deps_serialized, root_framework_rid_fallback_graph);
+ resolve_additional_deps(additional_deps_serialized, root_framework_rid_fallback_graph);
- setup_probe_config(args);
+ setup_probe_config(shared_stores, additional_probe_paths);
}
bool valid(pal::string_t* errors)
private:
void setup_shared_store_probes(
- const arguments_t& args);
+ const std::vector<pal::string_t>& shared_stores);
void setup_probe_config(
- const arguments_t& args);
+ const std::vector<pal::string_t>& shared_stores,
+ const std::vector<pal::string_t>& additional_probe_paths);
void init_known_entry_path(
const deps_entry_t& entry,
const pal::string_t& path);
void resolve_additional_deps(
- const pal::string_t& additional_deps_serialized,
+ const pal::char_t* additional_deps_serialized,
const deps_json_t::rid_fallback_graph_t* rid_fallback_graph);
const deps_json_t& get_app_deps() const
${CMAKE_CURRENT_LIST_DIR}/hostpolicy_context.cpp
${CMAKE_CURRENT_LIST_DIR}/hostpolicy.cpp
${CMAKE_CURRENT_LIST_DIR}/hostpolicy_init.cpp
+ ${CMAKE_CURRENT_LIST_DIR}/shared_store.cpp
${CMAKE_CURRENT_LIST_DIR}/../bundle/dir_utils.cpp
${CMAKE_CURRENT_LIST_DIR}/../bundle/extractor.cpp
${CMAKE_CURRENT_LIST_DIR}/../bundle/file_entry.cpp
${CMAKE_CURRENT_LIST_DIR}/deps_resolver.h
${CMAKE_CURRENT_LIST_DIR}/hostpolicy_context.h
${CMAKE_CURRENT_LIST_DIR}/hostpolicy_init.h
+ ${CMAKE_CURRENT_LIST_DIR}/shared_store.h
${CMAKE_CURRENT_LIST_DIR}/../hostpolicy.h
${CMAKE_CURRENT_LIST_DIR}/../corehost_context_contract.h
${CMAKE_CURRENT_LIST_DIR}/../bundle/dir_utils.h
#include <hostpolicy.h>
#include "hostpolicy_context.h"
#include "bundle/runner.h"
+#include "shared_store.h"
namespace
{
arguments_t args;
if (!init_arguments(
component_main_assembly_path,
- g_init.host_info,
- g_init.tfm,
host_mode,
- /* additional_deps_serialized */ pal::string_t(), // Additional deps - don't use those from the app, they're already in the app
/* deps_file */ pal::string_t(), // Avoid using any other deps file than the one next to the component
- g_init.probe_paths,
/* init_from_file_system */ true,
args))
{
deps_resolver_t resolver(
args,
component_fx_definitions,
+ /* additional_deps_serialized */ nullptr, // Additional deps - don't use those from the app, they're already in the app
+ shared_store::get_paths(g_init.tfm, host_mode, g_init.host_info.host_path),
+ g_init.probe_paths,
&g_init.root_rid_fallback_graph,
true);
#include <trace.h>
#include "bundle/runner.h"
#include "bundle/file_entry.h"
+#include "shared_store.h"
namespace
{
{
application = args.managed_application;
host_mode = hostpolicy_init.host_mode;
- host_path = args.host_path;
+ host_path = hostpolicy_init.host_info.host_path;
breadcrumbs_enabled = enable_breadcrumbs;
deps_resolver_t resolver
- {
- args,
- hostpolicy_init.fx_definitions,
- /* root_framework_rid_fallback_graph */ nullptr, // This means that the fx_definitions contains the root framework
- hostpolicy_init.is_framework_dependent
- };
+ {
+ args,
+ hostpolicy_init.fx_definitions,
+ hostpolicy_init.additional_deps_serialized.c_str(),
+ shared_store::get_paths(hostpolicy_init.tfm, host_mode, host_path),
+ hostpolicy_init.probe_paths,
+ /* root_framework_rid_fallback_graph */ nullptr, // This means that the fx_definitions contains the root framework
+ hostpolicy_init.is_framework_dependent
+ };
pal::string_t resolver_errors;
if (!resolver.valid(&resolver_errors))
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+#include "shared_store.h"
+#include <trace.h>
+#include <utils.h>
+
+#define RUNTIME_STORE_DIRECTORY_NAME _X("store")
+#define SHARED_STORE_ENV _X("DOTNET_SHARED_STORE")
+
+namespace
+{
+ void get_env_dirs(std::vector<pal::string_t>& dirs, const pal::char_t* arch, const pal::string_t& tfm)
+ {
+ pal::string_t path;
+ if (!pal::getenv(SHARED_STORE_ENV, &path))
+ return;
+
+ pal::string_t tok;
+ pal::stringstream_t ss(path);
+ while (std::getline(ss, tok, PATH_SEPARATOR))
+ {
+ if (pal::realpath(&tok))
+ {
+ append_path(&tok, arch);
+ append_path(&tok, tfm.c_str());
+ dirs.push_back(tok);
+
+ trace::verbose(_X("Shared store (%s): '%s'"), SHARED_STORE_ENV, tok.c_str());
+ }
+ }
+ }
+
+ void get_global_dirs(std::vector<pal::string_t>& dirs, const pal::char_t* arch, const pal::string_t& tfm, const pal::string_t& dir_to_skip)
+ {
+ std::vector<pal::string_t> global_dirs;
+ if (!pal::get_global_dotnet_dirs(&global_dirs))
+ return;
+
+ for (pal::string_t dir : global_dirs)
+ {
+ append_path(&dir, RUNTIME_STORE_DIRECTORY_NAME);
+ append_path(&dir, arch);
+ append_path(&dir, tfm.c_str());
+ if (!dir_to_skip.empty() && pal::are_paths_equal_with_normalized_casing(dir, dir_to_skip))
+ continue;
+
+ dirs.push_back(dir);
+ trace::verbose(_X("Shared store (%s): '%s'"), _X("global"), dir.c_str());
+ }
+ }
+}
+
+/**
+ * Get the shared store directories.
+ *
+ * - DOTNET_SHARED_STORE environment variable - multiple delimited paths + <arch>\<tfm>
+ * - dotnet.exe relative shared store\<arch>\<tfm>
+ * - Global location
+ * Windows: global default location (Program Files) or globally registered location (registry) + store\<arch>\<tfm>
+ * Linux/macOS: none (no global locations are considered)
+ */
+std::vector<pal::string_t> shared_store::get_paths(const pal::string_t& tfm, host_mode_t host_mode, const pal::string_t& host_path)
+{
+ std::vector<pal::string_t> shared_stores;
+
+ // Old (MNA < 1.1.*) "runtimeconfig.json" files do not contain TFM property.
+ if (tfm.empty())
+ return shared_stores;
+
+ const pal::char_t* arch = get_current_arch_name();
+
+ // Environment variable DOTNET_SHARED_STORE
+ get_env_dirs(shared_stores, arch, tfm);
+
+ // "dotnet.exe" relative shared store folder
+ pal::string_t dotnet_shared_store;
+ if (host_mode == host_mode_t::muxer)
+ {
+ dotnet_shared_store = get_directory(host_path);
+ append_path(&dotnet_shared_store, RUNTIME_STORE_DIRECTORY_NAME);
+ append_path(&dotnet_shared_store, arch);
+ append_path(&dotnet_shared_store, tfm.c_str());
+ shared_stores.push_back(dotnet_shared_store);
+ trace::verbose(_X("Shared store (%s): '%s'"), _X("dotnet"), dotnet_shared_store.c_str());
+ }
+
+ // Global shared store dir
+ bool multilevel_lookup = multilevel_lookup_enabled();
+ if (multilevel_lookup)
+ {
+ get_global_dirs(shared_stores, arch, tfm, dotnet_shared_store);
+ }
+
+ return shared_stores;
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+#ifndef SHARED_STORE_H
+#define SHARED_STORE_H
+
+#include <host_interface.h>
+#include <pal.h>
+
+namespace shared_store
+{
+ std::vector<pal::string_t> get_paths(const pal::string_t& tfm, host_mode_t host_mode, const pal::string_t& host_path);
+}
+
+#endif // SHARED_STORE_H