}
else
{
- // Check default installation root as fallback
- if (!pal::get_default_installation_dir(&default_install_location))
+ if (pal::get_dotnet_self_registered_dir(&default_install_location) || pal::get_default_installation_dir(&default_install_location))
+ {
+ trace::info(_X("Using global installation location [%s] as runtime location."), default_install_location.c_str());
+ out_dotnet_root->assign(default_install_location);
+ }
+ else
{
trace::error(_X("A fatal error occurred, the default install location cannot be obtained."));
return false;
}
- trace::info(_X("Using default installation location [%s] as runtime location."), default_install_location.c_str());
- out_dotnet_root->assign(default_install_location);
}
fxr_dir = *out_dotnet_root;
{
if (default_install_location.empty())
{
+ pal::get_dotnet_self_registered_dir(&default_install_location);
+ }
+ if (default_install_location.empty())
+ {
pal::get_default_installation_dir(&default_install_location);
}
trace::error(_X("A fatal error occurred. The required library %s could not be found.\n"
"If this is a self-contained application, that library should exist in [%s].\n"
- "If this is a framework-dependent application, install the runtime in the default location [%s] or use the %s environment variable to specify the runtime location."),
+ "If this is a framework-dependent application, install the runtime in the global location [%s] or use the %s environment variable to specify the runtime location."),
LIBFXR_NAME,
root_path.c_str(),
default_install_location.c_str(),
using System.IO;
using System.Security.Cryptography;
using System.Text;
+using System.Runtime.InteropServices;
+using Microsoft.Win32;
using Xunit;
namespace Microsoft.DotNet.CoreSetup.Test.HostActivation
.And.HaveStdOutContaining($"Framework Version:{sharedTestState.RepoDirectories.MicrosoftNETCoreAppVersion}");
}
+ [Fact]
+ public void Framework_Dependent_AppHost_From_Global_Registry_Location_Succeeds()
+ {
+ if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ {
+ return;
+ }
+
+ var fixture = sharedTestState.PortableAppFixture_Published
+ .Copy();
+
+ // Since SDK doesn't support building framework dependent apphost yet, emulate that behavior
+ // by creating the executable from apphost.exe
+ var appExe = fixture.TestProject.AppExe;
+ var appDllName = Path.GetFileName(fixture.TestProject.AppDll);
+
+ string hostExeName = RuntimeInformationExtensions.GetExeFileNameForCurrentPlatform("apphost");
+ string builtAppHost = Path.Combine(sharedTestState.RepoDirectories.HostArtifacts, hostExeName);
+ string appDir = Path.GetDirectoryName(appExe);
+ string appDirHostExe = Path.Combine(appDir, hostExeName);
+
+ // Make a copy of apphost first, replace hash and overwrite app.exe, rather than
+ // overwrite app.exe and edit in place, because the file is opened as "write" for
+ // the replacement -- the test fails with ETXTBSY (exit code: 26) in Linux when
+ // executing a file opened in "write" mode.
+ File.Copy(builtAppHost, appDirHostExe, true);
+ using (var sha256 = SHA256.Create())
+ {
+ // Replace the hash with the managed DLL name.
+ var hash = sha256.ComputeHash(Encoding.UTF8.GetBytes("foobar"));
+ var hashStr = BitConverter.ToString(hash).Replace("-", "").ToLower();
+ AppHostExtensions.SearchAndReplace(appDirHostExe, Encoding.UTF8.GetBytes(hashStr), Encoding.UTF8.GetBytes(appDllName), true);
+ }
+ File.Copy(appDirHostExe, appExe, true);
+
+ // Get the framework location that was built
+ string builtDotnet = fixture.BuiltDotnet.BinPath;
+
+ RegistryKey hkcu = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry32);
+ RegistryKey interfaceKey = hkcu.CreateSubKey(@"Software\Classes\Interface");
+ string testKeyName = "_DOTNET_Test" + System.Diagnostics.Process.GetCurrentProcess().Id.ToString();
+ RegistryKey testKey = interfaceKey.CreateSubKey(testKeyName);
+ try
+ {
+ string architecture = fixture.CurrentRid.Split('-')[1];
+ RegistryKey dotnetLocationKey = testKey.CreateSubKey($@"Setup\InstalledVersions\{architecture}");
+ dotnetLocationKey.SetValue("InstallLocation", builtDotnet);
+
+ // Verify running with the default working directory
+ Command.Create(appExe)
+ .CaptureStdErr()
+ .CaptureStdOut()
+ .EnvironmentVariable("_DOTNET_TEST_SDK_REGISTRY_PATH", testKey.Name)
+ .Execute()
+ .Should().Pass()
+ .And.HaveStdOutContaining("Hello World")
+ .And.HaveStdOutContaining($"Framework Version:{sharedTestState.RepoDirectories.MicrosoftNETCoreAppVersion}");
+
+ // Verify running from within the working directory
+ Command.Create(appExe)
+ .WorkingDirectory(fixture.TestProject.OutputDirectory)
+ .EnvironmentVariable("_DOTNET_TEST_SDK_REGISTRY_PATH", testKey.Name)
+ .CaptureStdErr()
+ .CaptureStdOut()
+ .Execute()
+ .Should().Pass()
+ .And.HaveStdOutContaining("Hello World")
+ .And.HaveStdOutContaining($"Framework Version:{sharedTestState.RepoDirectories.MicrosoftNETCoreAppVersion}");
+ }
+ finally
+ {
+ interfaceKey.DeleteSubKeyTree(testKeyName);
+ }
+ }
+
private string MoveDepsJsonToSubdirectory(TestProjectFixture testProjectFixture)
{
var subdirectory = Path.Combine(testProjectFixture.TestProject.ProjectDirectory, "d");