Skip to content

Commit 6204900

Browse files
committed
implement GAC search
1 parent 53aabd7 commit 6204900

File tree

1 file changed

+58
-31
lines changed

1 file changed

+58
-31
lines changed

src/fsharp/ReferenceResolver.fs

Lines changed: 58 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ type Resolver =
6565
logerror:(string->string->unit)
6666
-> ResolvedFile[]
6767

68-
let SimplisticResolver =
68+
let SimulatedMSBuildResolver =
6969
{ new Resolver with
7070
member __.HighestInstalledNetFrameworkVersion() = "v4.5"
7171
member __.DotNetFrameworkReferenceAssembliesRootDirectory =
@@ -119,7 +119,6 @@ let SimplisticResolver =
119119
yield! registrySearchPaths() ]
120120

121121
for (r, baggage) in references do
122-
try
123122
printfn "resolving %s" r
124123
let mutable found = false
125124
let success path =
@@ -128,29 +127,35 @@ let SimplisticResolver =
128127
found <- true
129128
results.Add { itemSpec = path; prepareToolTip = snd; baggage=baggage }
130129

131-
if not found && Path.IsPathRooted(r) then
132-
if FileSystem.SafeExists(r) then
133-
success r
130+
try
131+
if not found && Path.IsPathRooted(r) then
132+
if FileSystem.SafeExists(r) then
133+
success r
134+
with e -> logWarning "SR001" (e.ToString())
134135

135136
// For this one we need to get the version search exactly right, without doing a load
136-
if not found && r.StartsWith("FSharp.Core, Version=") && Environment.OSVersion.Platform = PlatformID.Win32NT then
137-
let n = AssemblyName(r)
138-
let fscoreDir0 =
139-
let PF =
140-
match Environment.GetEnvironmentVariable("ProgramFiles(x86)") with
141-
| null -> Environment.GetEnvironmentVariable("ProgramFiles")
142-
| s -> s
143-
PF + @"\Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\" + n.Version.ToString()
144-
let trialPath = Path.Combine(fscoreDir0,n.Name + ".dll")
145-
if FileSystem.SafeExists(trialPath) then
146-
success trialPath
137+
try
138+
if not found && r.StartsWith("FSharp.Core, Version=") && Environment.OSVersion.Platform = PlatformID.Win32NT then
139+
let n = AssemblyName(r)
140+
let fscoreDir0 =
141+
let PF =
142+
match Environment.GetEnvironmentVariable("ProgramFiles(x86)") with
143+
| null -> Environment.GetEnvironmentVariable("ProgramFiles")
144+
| s -> s
145+
PF + @"\Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\" + n.Version.ToString()
146+
let trialPath = Path.Combine(fscoreDir0,n.Name + ".dll")
147+
if FileSystem.SafeExists(trialPath) then
148+
success trialPath
149+
with e -> logWarning "SR001" (e.ToString())
147150

148151
// Try to use Assemby.Load rather than searching paths for assemblies with explicit versions
149-
if not found && r.Contains(",") then
150-
let ass = try Some (Assembly.Load(r)) with _ -> None
151-
match ass with
152-
| None -> ()
153-
| Some ass -> success ass.Location
152+
try
153+
if not found && r.Contains(",") then
154+
let ass = try Some (Assembly.Load(r)) with _ -> None
155+
match ass with
156+
| None -> ()
157+
| Some ass -> success ass.Location
158+
with e -> logWarning "SR001" (e.ToString())
154159

155160
let isFileName =
156161
r.EndsWith("dll",StringComparison.InvariantCultureIgnoreCase) ||
@@ -159,22 +164,43 @@ let SimplisticResolver =
159164
let qual = if isFileName then r else try AssemblyName(r).Name + ".dll" with _ -> r + ".dll"
160165

161166
for searchPath in searchPaths do
167+
try
162168
if not found then
163169
let trialPath = Path.Combine(searchPath,qual)
164170
if FileSystem.SafeExists(trialPath) then
165171
success trialPath
172+
with e -> logWarning "SR001" (e.ToString())
173+
174+
try
175+
// Seach the GAC on Windows
176+
if not found && not isFileName && Environment.OSVersion.Platform = PlatformID.Win32NT then
177+
let n = AssemblyName(r)
178+
let netfx = System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory()
179+
let gac = Path.Combine(Path.GetDirectoryName(Path.GetDirectoryName(netfx.TrimEnd('\\'))),"assembly")
180+
for gacdir in Directory.EnumerateDirectories(gac) do
181+
let assdir = Path.Combine(gacdir,n.Name)
182+
if Directory.Exists(assdir) then
183+
let verdir = Path.Combine(assdir,"v4.0_"+n.Version.ToString()+"__"+String.concat "" [| for b in n.GetPublicKeyToken() -> sprintf "%02x" b |])
184+
printfn "searching GAC: %s" verdir
185+
186+
if Directory.Exists(verdir) then
187+
let trialPath = Path.Combine(verdir,qual)
188+
printfn "searching GAC: %s" trialPath
189+
if FileSystem.SafeExists(trialPath) then
190+
success trialPath
191+
with e -> logWarning "SR001" (e.ToString())
192+
166193

167194
//if not found then
168195
// let ass = try Some (Assembly.Load(r)) with _ -> None
169196
// match ass with
170197
// | Some ass -> success ass.Location
171198
// | None -> ()
172-
with e -> logWarning "SR001" (e.ToString())
173199
results.ToArray() }
174200

175201
#if INTERACTIVE
176-
SimplisticResolver.DotNetFrameworkReferenceAssembliesRootDirectory
177-
SimplisticResolver.HighestInstalledNetFrameworkVersion()
202+
SimulatedMSBuildResolver.DotNetFrameworkReferenceAssembliesRootDirectory
203+
SimulatedMSBuildResolver.HighestInstalledNetFrameworkVersion()
178204

179205
let fscoreDir =
180206
if System.Environment.OSVersion.Platform = System.PlatformID.Win32NT then // file references only valid on Windows
@@ -187,26 +213,27 @@ let fscoreDir =
187213
System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory()
188214

189215
let resolve s =
190-
SimplisticResolver.Resolve(ResolutionEnvironment.CompileTimeLike,[| for a in s -> (a, "") |],"v4.5.1", [SimplisticResolver.DotNetFrameworkReferenceAssembliesRootDirectory + @"\v4.5.1" ],"", "", fscoreDir,[],__SOURCE_DIRECTORY__,ignore, (fun _ _ -> ()), (fun _ _-> ()))
216+
SimulatedMSBuildResolver.Resolve(ResolutionEnvironment.CompileTimeLike,[| for a in s -> (a, "") |],"v4.5.1", [SimulatedMSBuildResolver.DotNetFrameworkReferenceAssembliesRootDirectory + @"\v4.5.1" ],"", "", fscoreDir,[],__SOURCE_DIRECTORY__,ignore, (fun _ _ -> ()), (fun _ _-> ()))
191217

192218
resolve ["System"; "mscorlib"; "mscorlib.dll"; "FSharp.Core"; "FSharp.Core.dll"; "Microsoft.SqlServer.Dmf.dll"; "Microsoft.SqlServer.Dmf" ]
193219

194220
resolve [ "FSharp.Core, Version=4.4.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" ]
221+
222+
resolve [ "EventViewer, Version=6.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" ]
195223
#endif
196224

197225
let GetDefaultResolver(msbuildEnabled: bool, msbuildVersion: string option) =
198226
let msbuildEnabled = msbuildEnabled && false
227+
let msbuildVersion = defaultArg msbuildVersion "12"
199228
let tryMSBuild v =
200-
if msbuildEnabled then
201-
// Detect if MSBuild v12 is on the machine, if so use the resolver from there
229+
// Detect if MSBuild is on the machine, if so use the resolver from there
202230
let mb = try Assembly.Load(sprintf "Microsoft.Build.Framework, Version=%s.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" v) |> Option.ofObj with _ -> None
203231
let ass = mb |> Option.bind (fun _ -> try Assembly.Load(sprintf "FSharp.Compiler.Service.MSBuild.v%s" v) |> Option.ofObj with _ -> None)
204232
let ty = ass |> Option.bind (fun ass -> ass.GetType("Microsoft.FSharp.Compiler.MSBuildReferenceResolver") |> Option.ofObj)
205233
let obj = ty |> Option.bind (fun ty -> ty.InvokeMember("get_Resolver",BindingFlags.Static ||| BindingFlags.Public ||| BindingFlags.InvokeMethod ||| BindingFlags.NonPublic, null, null, [| |]) |> Option.ofObj)
206234
let resolver = obj |> Option.bind (fun obj -> match obj with :? Resolver as r -> Some r | _ -> None)
207235
resolver
208-
else None
209-
match tryMSBuild (defaultArg msbuildVersion "12") with
236+
match (if msbuildEnabled then tryMSBuild msbuildVersion else None) with
210237
| Some r -> r
211238
| None ->
212239
//match tryMSBuild "15" with
@@ -215,7 +242,7 @@ let GetDefaultResolver(msbuildEnabled: bool, msbuildVersion: string option) =
215242
//match tryMSBuild "14" with
216243
//| Some r -> r
217244
//| None ->
218-
match tryMSBuild "12" with
245+
match (if msbuildEnabled && msbuildVersion <> "12" then tryMSBuild "12" else None) with
219246
| Some r -> r
220247
| None ->
221-
SimplisticResolver
248+
SimulatedMSBuildResolver

0 commit comments

Comments
 (0)