コード例 #1
0
    private static void FindExtension()
    {
        if (_looked)
        {
            return;
        }

        bool hasDependencyContext;

        try
        {
            hasDependencyContext = DependencyContext.Default != null;
        }
        catch (Exception ex) // Work around dotnet/core-setup#4556
        {
            Debug.Fail(ex.ToString());
            hasDependencyContext = false;
        }

        if (hasDependencyContext)
        {
            var candidateAssets = new Dictionary <(string, string), int>();
            var rid             = RuntimeInformation.RuntimeIdentifier;
            var rids            = DependencyContext.Default !.RuntimeGraph.FirstOrDefault(g => g.Runtime == rid)?.Fallbacks.ToList()
                                  ?? new List <string?>();
            rids.Insert(0, rid);

            foreach (var library in DependencyContext.Default.RuntimeLibraries)
            {
                foreach (var group in library.NativeLibraryGroups)
                {
                    foreach (var file in group.RuntimeFiles)
                    {
                        if (string.Equals(
                                Path.GetFileName(file.Path),
                                "mod_spatialite" + SharedLibraryExtension,
                                StringComparison.OrdinalIgnoreCase))
                        {
                            var fallbacks = rids.IndexOf(group.Runtime);
                            if (fallbacks != -1 && library.Path is not null)
                            {
                                candidateAssets.Add((library.Path, file.Path), fallbacks);
                            }
                        }
                    }
                }
            }

            var assetPath = candidateAssets.OrderBy(p => p.Value)
                            .Select(p => p.Key).FirstOrDefault();
            if (assetPath != default)
            {
                string?assetDirectory;
                if (File.Exists(Path.Combine(AppContext.BaseDirectory, assetPath.Item2)))
                {
                    // NB: This enables framework-dependent deployments
                    assetDirectory = Path.Combine(
                        AppContext.BaseDirectory,
                        Path.GetDirectoryName(assetPath.Item2.Replace('/', Path.DirectorySeparatorChar)) !);
                }
                else
                {
                    string?assetFullPath      = null;
                    var    probingDirectories = ((string)AppDomain.CurrentDomain.GetData("PROBING_DIRECTORIES") !)
                                                .Split(Path.PathSeparator);
                    foreach (var directory in probingDirectories)
                    {
                        var candidateFullPath = Path.Combine(
                            directory,
                            (assetPath.Item1 + "/" + assetPath.Item2).Replace('/', Path.DirectorySeparatorChar));
                        if (File.Exists(candidateFullPath))
                        {
                            assetFullPath = candidateFullPath;
                        }
                    }

                    Check.DebugAssert(assetFullPath != null, "assetFullPath is null");

                    assetDirectory = Path.GetDirectoryName(assetFullPath);
                }

                Check.DebugAssert(assetDirectory != null, "assetDirectory is null");

                // GetEnvironmentVariable can sometimes return null when there is a race condition
                // with another thread setting it. Therefore we do a bit of back off and retry here.
                // Note that the result can be null if no path is set on the system.
                var delay       = 1;
                var currentPath = Environment.GetEnvironmentVariable(PathVariableName !);
                while (currentPath == null && delay < 1000)
                {
                    Thread.Sleep(delay);
                    delay      *= 2;
                    currentPath = Environment.GetEnvironmentVariable(PathVariableName !);
                }

                if (currentPath == null ||
                    !currentPath.Split(Path.PathSeparator).Any(
                        p => string.Equals(
                            p.TrimEnd(Path.DirectorySeparatorChar),
                            assetDirectory,
                            StringComparison.OrdinalIgnoreCase)))
                {
                    Environment.SetEnvironmentVariable(
                        PathVariableName !,
                        assetDirectory + Path.PathSeparator + currentPath);
                }
            }
        }

        _looked = true;
    }