The host will probe in the following order of precedence for `dotnet run` and application activations post `dotnet publish`:
+ `$CORE_SERVICING` on Unix or `%ProgramFiles(x86)%\coreservicing` on Windows.
++ Application Bin and Shared FX directory
+ `DOTNET_SHARED_STORE` in the chained order
-+ The dotnet.exe relative shared package store
-+ The global shared package store
-+ The Shared Framework directory
-+ ~~`DOTNET_HOSTING_OPTIMIZATION_CACHE` deprecated in favor of `DOTNET_SHARED_STORE`~~
-+ `--additionalprobingpaths` specified in the command line
-+ `runtimeOptions.additionalProbingPaths` (includes NuGet cache probe specified by the CLI for `dotnet run`)
-+ Application `bin` directory
-
++ Store locations
+ - The dotnet.exe relative shared package store
+ - The global shared package store
+ - ~~`DOTNET_HOSTING_OPTIMIZATION_CACHE` deprecated in favor of `DOTNET_SHARED_STORE`~~
++ Additional Probing Paths
+ - `--additionalprobingpaths` specified in the command line
+ - `runtimeOptions.additionalProbingPaths` (includes NuGet cache probe specified by the CLI for `dotnet run`)
+
+**NOTE:** `--additionalprobingpaths` can be passed template paths like below and the host will interpret `|arch|/|tfm|` appropriately to look for assets:
+ `%USERPROFILE%\user\cache\|arch|\|tfm|` or `$HOME/user/cache/|arch|/|tfm|`
## dotnet publish
Publish will be enhanced to support a filter profile file specified as xml. This file explicitly lists all asset packages that need to be trimmed out of the publish output. The following are examples of how various application types can be published.
}
// Convert "path" to realpath (merging working dir if needed) and append to "realpaths" out param.
-void append_realpath(const pal::string_t& path, std::vector<pal::string_t>* realpaths)
+void append_probe_realpath(const pal::string_t& path, std::vector<pal::string_t>* realpaths, const pal::string_t& tfm)
{
- pal::string_t real = path;
- if (pal::realpath(&real))
+ pal::string_t probe_path = path;
+
+ if (pal::realpath(&probe_path) && pal::directory_exists(probe_path))
+ {
+ realpaths->push_back(probe_path);
+ }
+ else
{
- realpaths->push_back(real);
+ //Check if we can extrapolate |arch|<DIR_SEPARATOR>|tfm| for probing stores
+ pal::string_t placeholder = _X("|arch|");
+ placeholder.push_back(DIR_SEPARATOR);
+ placeholder.append(_X("|tfm|"));
+ auto pos_placeholder = probe_path.find_last_of(placeholder);
+
+ if (pos_placeholder != pal::string_t::npos)
+ {
+ pal::string_t segment = get_arch();
+ segment.push_back(DIR_SEPARATOR);
+ segment.append(tfm);
+ probe_path.replace(pos_placeholder - placeholder.length() + 1, placeholder.length(), segment);
+
+ if (pal::directory_exists(probe_path))
+ {
+ realpaths->push_back(probe_path);
+ }
+ else
+ {
+ trace::verbose(_X("Ignoring host interpreted additional probing path %s as it does not exist."),probe_path.c_str());
+ }
+ }
+ else
+ {
+ trace::verbose(_X("Ignoring additional probing path %s as it does not exist."),probe_path.c_str());
+ }
}
}
std::vector<pal::string_t> probe_realpaths;
for (const auto& path : spec_probe_paths)
{
- append_realpath(path, &probe_realpaths);
+ append_probe_realpath(path, &probe_realpaths, config.get_tfm());
}
for (const auto& path : config.get_probe_paths())
{
- append_realpath(path, &probe_realpaths);
+ append_probe_realpath(path, &probe_realpaths, config.get_tfm());
}
// 'Roll forward on no candidate fx' is disabled by default. It can be enabled through: