public virtual TestProcessStartInfo GetTestHostProcessStartInfo()

in src/Microsoft.TestPlatform.TestHostProvider/Hosting/DotnetTestHostManager.cs [200:306]


    public virtual TestProcessStartInfo GetTestHostProcessStartInfo(
        IEnumerable<string> sources,
        IDictionary<string, string> environmentVariables,
        TestRunnerConnectionInfo connectionInfo)
    {
        EqtTrace.Verbose($"DotnetTestHostmanager.GetTestHostProcessStartInfo: Platform environment '{_platformEnvironment.Architecture}' target architecture '{_architecture}' framework '{_targetFramework}' OS '{_platformEnvironment.OperatingSystem}'");

        var startInfo = new TestProcessStartInfo();

        // .NET core host manager is not a shared host. It will expect a single test source to be provided.
        // TODO: Throw an exception when we get 0 or more than 1 source, that explains what happened, instead of .Single throwing a generic exception?
        var args = string.Empty;
        var sourcePath = sources.Single();
        var sourceFile = Path.GetFileNameWithoutExtension(sourcePath);
        var sourceDirectory = Path.GetDirectoryName(sourcePath);

        // Probe for runtime config and deps file for the test source
        var runtimeConfigPath = Path.Combine(sourceDirectory, string.Concat(sourceFile, ".runtimeconfig.json"));
        var runtimeConfigFound = false;
        if (_fileHelper.Exists(runtimeConfigPath))
        {
            runtimeConfigFound = true;
            string argsToAdd = " --runtimeconfig " + runtimeConfigPath.AddDoubleQuote();
            args += argsToAdd;
            EqtTrace.Verbose("DotnetTestHostmanager: Adding {0} in args", argsToAdd);
        }
        else
        {
            EqtTrace.Verbose("DotnetTestHostmanager: File {0}, does not exist", runtimeConfigPath);
        }

        // Use the deps.json for test source
        var depsFilePath = Path.Combine(sourceDirectory, string.Concat(sourceFile, ".deps.json"));
        if (_fileHelper.Exists(depsFilePath))
        {
            string argsToAdd = " --depsfile " + depsFilePath.AddDoubleQuote();
            args += argsToAdd;
            EqtTrace.Verbose("DotnetTestHostmanager: Adding {0} in args", argsToAdd);
        }
        else
        {
            EqtTrace.Verbose("DotnetTestHostmanager: File {0}, does not exist", depsFilePath);
        }

        var runtimeConfigDevPath = Path.Combine(sourceDirectory, string.Concat(sourceFile, ".runtimeconfig.dev.json"));
        string testHostPath = string.Empty;
        bool useCustomDotnetHostpath = !string.IsNullOrEmpty(_dotnetHostPath);

        if (useCustomDotnetHostpath)
        {
            EqtTrace.Verbose("DotnetTestHostmanager: User specified custom path to dotnet host: '{0}'.", _dotnetHostPath);
        }

        // Try find testhost.exe (or the architecture specific version). We ship those ngened executables for Windows because they have faster startup time. We ship them only for some platforms.
        // When user specified path to dotnet.exe don't try to find the exexutable, because we will always use the testhost.dll together with their dotnet.exe.
        // We use dotnet.exe on Windows/ARM.
        bool testHostExeFound = false;
        if (!useCustomDotnetHostpath
            && _platformEnvironment.OperatingSystem.Equals(PlatformOperatingSystem.Windows)

            // testhost*.exe are build for netcoreapp2.1 and are not able to search for the correct runtime in case of x64/x86 on arm because the new logic(registry lookup)
            // was added in since netcoreapp3.0. On arm we cannot rely on apphost and we'll use dotnet.exe muxer
            && !IsWinOnArm())
        {
            // testhost.exe is 64-bit and has no suffix other versions have architecture suffix.
            var exeName = _architecture == Architecture.X64 || _architecture == Architecture.Default || _architecture == Architecture.AnyCPU
                ? "testhost.exe"
                : $"testhost.{_architecture.ToString().ToLowerInvariant()}.exe";

            var fullExePath = Path.Combine(sourceDirectory, exeName);

            // check for testhost.exe in sourceDirectory. If not found, check in nuget folder.
            if (_fileHelper.Exists(fullExePath))
            {
                EqtTrace.Verbose($"DotnetTestHostManager: {exeName} found at path: " + fullExePath);
                startInfo.FileName = fullExePath;
                testHostExeFound = true;
            }
            else
            {
                // Check if testhost.dll is found in nuget folder or next to the test.dll, and use that to locate testhost.exe that is in the build folder in the same Nuget package.
                testHostPath = GetTestHostPath(runtimeConfigDevPath, depsFilePath, sourceDirectory);
                if (!string.IsNullOrWhiteSpace(testHostPath) && testHostPath.IndexOf("microsoft.testplatform.testhost", StringComparison.OrdinalIgnoreCase) >= 0)
                {
                    // testhost.dll is present in path {testHostNugetRoot}\lib\netcoreapp2.1\testhost.dll
                    // testhost.(x86).exe is present in location {testHostNugetRoot}\build\netcoreapp2.1\{x86/x64}\{testhost.x86.exe/testhost.exe}
                    var folderName = _architecture == Architecture.X64 || _architecture == Architecture.Default || _architecture == Architecture.AnyCPU
                        ? Architecture.X64.ToString().ToLowerInvariant()
                        : _architecture.ToString().ToLowerInvariant();

                    var testHostNugetRoot = new DirectoryInfo(testHostPath).Parent.Parent.Parent;

#if DOTNET_BUILD_FROM_SOURCE
                    var testHostExeNugetPath = Path.Combine(testHostNugetRoot.FullName, "build", "net6.0", folderName, exeName);
#else
                    var testHostExeNugetPath = Path.Combine(testHostNugetRoot.FullName, "build", "netcoreapp2.1", folderName, exeName);
#endif

                    if (_fileHelper.Exists(testHostExeNugetPath))
                    {
                        EqtTrace.Verbose("DotnetTestHostManager: Testhost.exe/testhost.x86.exe found at path: " + testHostExeNugetPath);
                        startInfo.FileName = testHostExeNugetPath;
                        testHostExeFound = true;
                    }
                }
            }
        }