未验证 提交 802e030d 编写于 作者: K Kevin Ransom (msft) 提交者: GitHub

NativeDllResolveHandler (#13355)

上级 8150e644
...@@ -11,12 +11,58 @@ open Internal.Utilities ...@@ -11,12 +11,58 @@ open Internal.Utilities
open Internal.Utilities.FSharpEnvironment open Internal.Utilities.FSharpEnvironment
open FSharp.Compiler.IO open FSharp.Compiler.IO
type internal ProbingPathsStore() =
let addedPaths = ConcurrentBag<string>()
static member AppendPathSeparator (p: string) =
let separator = string Path.PathSeparator
if not (p.EndsWith(separator, StringComparison.OrdinalIgnoreCase)) then
p + separator
else
p
static member RemoveProbeFromProcessPath probePath =
if not (String.IsNullOrWhiteSpace(probePath)) then
let probe = ProbingPathsStore.AppendPathSeparator probePath
let path = ProbingPathsStore.AppendPathSeparator (Environment.GetEnvironmentVariable("PATH"))
if path.Contains(probe) then
Environment.SetEnvironmentVariable("PATH", path.Replace(probe, ""))
member _.AddProbeToProcessPath probePath =
let probe = ProbingPathsStore.AppendPathSeparator probePath
let path = ProbingPathsStore.AppendPathSeparator (Environment.GetEnvironmentVariable("PATH"))
if not (path.Contains(probe)) then
Environment.SetEnvironmentVariable("PATH", path + probe)
addedPaths.Add probe
member this.RefreshPathsInEnvironment(roots) =
for probePath in roots do
this.AddProbeToProcessPath(probePath)
member this.Dispose() =
let mutable probe: string = Unchecked.defaultof<string>
while (addedPaths.TryTake(&probe)) do
ProbingPathsStore.RemoveProbeFromProcessPath(probe)
interface IDisposable with
member _.Dispose() =
let mutable probe: string = Unchecked.defaultof<string>
while (addedPaths.TryTake(&probe)) do
ProbingPathsStore.RemoveProbeFromProcessPath(probe)
/// Signature for Native library resolution probe callback /// Signature for Native library resolution probe callback
/// host implements this, it's job is to return a list of package roots to probe. /// host implements this, it's job is to return a list of package roots to probe.
type NativeResolutionProbe = delegate of Unit -> seq<string> type NativeResolutionProbe = delegate of Unit -> seq<string>
/// Type that encapsulates Native library probing for managed packages /// Type that encapsulates Native library probing for managed packages
type NativeDllResolveHandlerCoreClr(nativeProbingRoots: NativeResolutionProbe option) = type internal NativeDllResolveHandlerCoreClr(nativeProbingRoots: NativeResolutionProbe option) =
let probingPaths = new ProbingPathsStore()
let nativeLibraryTryLoad = let nativeLibraryTryLoad =
let nativeLibraryType: Type = let nativeLibraryType: Type =
...@@ -116,57 +162,28 @@ type NativeDllResolveHandlerCoreClr(nativeProbingRoots: NativeResolutionProbe op ...@@ -116,57 +162,28 @@ type NativeDllResolveHandlerCoreClr(nativeProbingRoots: NativeResolutionProbe op
do eventInfo.AddEventHandler(defaultAssemblyLoadContext, handler) do eventInfo.AddEventHandler(defaultAssemblyLoadContext, handler)
interface IDisposable with member _.RefreshPathsInEnvironment(roots: string seq) =
member _x.Dispose() = probingPaths.RefreshPathsInEnvironment(roots)
eventInfo.RemoveEventHandler(defaultAssemblyLoadContext, handler)
type NativeDllResolveHandler(nativeProbingRoots: NativeResolutionProbe option) =
let handler: IDisposable option =
if isRunningOnCoreClr then
Some(new NativeDllResolveHandlerCoreClr(nativeProbingRoots) :> IDisposable)
else
None
let appendPathSeparator (p: string) =
let separator = string Path.PathSeparator
if not (p.EndsWith(separator, StringComparison.OrdinalIgnoreCase)) then
p + separator
else
p
let addedPaths = ConcurrentBag<string>()
let addProbeToProcessPath probePath = member _.Dispose() =
let probe = appendPathSeparator probePath eventInfo.RemoveEventHandler(defaultAssemblyLoadContext, handler)
let path = appendPathSeparator (Environment.GetEnvironmentVariable("PATH")) probingPaths.Dispose()
if not (path.Contains(probe)) then interface IDisposable with
Environment.SetEnvironmentVariable("PATH", path + probe) member this.Dispose() = this.Dispose()
addedPaths.Add probe
let removeProbeFromProcessPath probePath = type NativeDllResolveHandler(nativeProbingRoots: NativeResolutionProbe option) =
if not (String.IsNullOrWhiteSpace(probePath)) then
let probe = appendPathSeparator probePath
let path = appendPathSeparator (Environment.GetEnvironmentVariable("PATH"))
if path.Contains(probe) then let handler: NativeDllResolveHandlerCoreClr option =
Environment.SetEnvironmentVariable("PATH", path.Replace(probe, "")) nativeProbingRoots
|> Option.filter(fun _ -> isRunningOnCoreClr)
|> Option.map (fun _ -> new NativeDllResolveHandlerCoreClr(nativeProbingRoots))
new(nativeProbingRoots: NativeResolutionProbe) = new NativeDllResolveHandler(Option.ofObj nativeProbingRoots) new(nativeProbingRoots: NativeResolutionProbe) = new NativeDllResolveHandler(Option.ofObj nativeProbingRoots)
member internal _.RefreshPathsInEnvironment(roots: string seq) = member internal _.RefreshPathsInEnvironment(roots: string seq) =
for probePath in roots do handler |> Option.iter (fun handler -> handler.RefreshPathsInEnvironment(roots))
addProbeToProcessPath probePath
interface IDisposable with interface IDisposable with
member _.Dispose() = member _.Dispose() =
match handler with handler |> Option.iter (fun handler -> handler.Dispose())
| None -> ()
| Some handler -> handler.Dispose()
let mutable probe: string = Unchecked.defaultof<string>
while (addedPaths.TryTake(&probe)) do
removeProbeFromProcessPath probe
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册