@@ -65,10 +65,13 @@ type Resolver =
6565 logerror:( string-> string-> unit)
6666 -> ResolvedFile[]
6767
68- let ScriptingNaiveResolver =
68+ let SimulatedMSBuildResolver =
6969 { new Resolver with
7070 member __.HighestInstalledNetFrameworkVersion () = " v4.5"
7171 member __.DotNetFrameworkReferenceAssembliesRootDirectory =
72+ #if RESHAPED_ MSBUILD
73+ " "
74+ #else
7275 if System.Environment.OSVersion.Platform = System.PlatformID.Win32NT then
7376 let PF =
7477 match Environment.GetEnvironmentVariable( " ProgramFiles(x86)" ) with
@@ -77,10 +80,12 @@ let ScriptingNaiveResolver =
7780 PF + @" \Reference Assemblies\Microsoft\Framework\.NETFramework"
7881 else
7982 " "
83+ #endif
8084
8185 member __.Resolve ( resolutionEnvironment , references , targetFrameworkVersion , targetFrameworkDirectories , targetProcessorArchitecture ,
8286 outputDirectory , fsharpCoreDir , explicitIncludeDirs , implicitIncludeDir , logMessage , logWarning , logError ) =
8387
88+ #if ! RESHAPED_ MSBUILD
8489 let registrySearchPaths () =
8590 [ let registryKey = @" Software\Microsoft\.NetFramework" ;
8691 use key = Registry.LocalMachine.OpenSubKey( registryKey)
@@ -107,79 +112,126 @@ let ScriptingNaiveResolver =
107112 match subSubSubKey.GetValue( null ) with
108113 | : ? string as s -> yield s
109114 | _ -> () ]
115+ #endif
110116
111-
117+ let results = ResizeArray ()
112118 let searchPaths =
113119 [ yield ! targetFrameworkDirectories
114120 yield ! explicitIncludeDirs
115121 yield fsharpCoreDir
116122 yield implicitIncludeDir
123+ #if ! RESHAPED_ MSBUILD
117124 if System.Environment.OSVersion.Platform = System.PlatformID.Win32NT then
118- yield ! registrySearchPaths() ]
125+ yield ! registrySearchPaths()
126+ #endif
127+ ]
119128
120- [| for ( baggage, r) in references do
129+ for ( r, baggage) in references do
130+ //printfn "resolving %s" r
121131 let mutable found = false
122132 let success path =
123133 if not found then
134+ //printfn "resolved %s --> %s" r path
124135 found <- true
125- [ { itemSpec = path; prepareToolTip = snd; baggage= baggage } ]
126- else []
127- if Path.IsPathRooted( r) then
128- if FileSystem.SafeExists( r) then
129- yield ! success r
130- else
131- let isFileName =
132- r.EndsWith( " dll" , StringComparison.InvariantCultureIgnoreCase) ||
133- r.EndsWith( " exe" , StringComparison.InvariantCultureIgnoreCase)
134-
135- let qual = if isFileName then r else try AssemblyName( r) .Name + " .dll" with _ -> r + " .dll"
136-
137- for searchPath in searchPaths do
138- if not found then
139- let trialPath = Path.Combine( searchPath, qual)
140- if FileSystem.SafeExists( trialPath) then
141- yield ! success trialPath
142- if not found then
143- let ass = try Some ( System.Reflection.Assembly.ReflectionOnlyLoad( r)) with _ -> None
144- match ass with
145- | None -> ()
146- | Some ass -> yield ! success ass.Location |] }
136+ results.Add { itemSpec = path; prepareToolTip = snd; baggage= baggage }
147137
148- #if INTERACTIVE
149- ScriptingNaiveResolver.DotNetFrameworkReferenceAssembliesRootDirectory
150- ScriptingNaiveResolver.HighestInstalledNetFrameworkVersion()
138+ try
139+ if not found && Path.IsPathRooted( r) then
140+ if FileSystem.SafeExists( r) then
141+ success r
142+ with e -> logWarning " SR001" ( e.ToString())
151143
152- let fscoreDir =
153- if System.Environment.OSVersion.Platform = System.PlatformID.Win32NT then // file references only valid on Windows
154- let PF =
155- match Environment.GetEnvironmentVariable( " ProgramFiles(x86)" ) with
156- | null -> Environment.GetEnvironmentVariable( " ProgramFiles" ) // if PFx86 is null, then we are 32-bit and just get PF
157- | s -> s
158- PF + @" \Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\4.4.0.0"
159- else
160- System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory()
144+ #if ! RESHAPED_ MSBUILD
145+ // For this one we need to get the version search exactly right, without doing a load
146+ try
147+ if not found && r.StartsWith( " FSharp.Core, Version=" ) && Environment.OSVersion.Platform = PlatformID.Win32NT then
148+ let n = AssemblyName( r)
149+ let fscoreDir0 =
150+ let PF =
151+ match Environment.GetEnvironmentVariable( " ProgramFiles(x86)" ) with
152+ | null -> Environment.GetEnvironmentVariable( " ProgramFiles" )
153+ | s -> s
154+ PF + @" \Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\" + n.Version.ToString()
155+ let trialPath = Path.Combine( fscoreDir0, n.Name + " .dll" )
156+ if FileSystem.SafeExists( trialPath) then
157+ success trialPath
158+ with e -> logWarning " SR001" ( e.ToString())
159+ #endif
161160
162- let resolve s =
163- ScriptingNaiveResolver.Resolve( ResolutionEnvironment.CompileTimeLike,[| for a in s -> ( " " , a) |], " v4.5.1" , [ ScriptingNaiveResolver.DotNetFrameworkReferenceAssembliesRootDirectory + @" \v4.5.1" ], " " , " " , fscoreDir,[],__ SOURCE_ DIRECTORY__, ignore, ( fun _ _ -> ()), ( fun _ _ -> ()))
161+ let isFileName =
162+ r.EndsWith( " dll" , StringComparison.OrdinalIgnoreCase) ||
163+ r.EndsWith( " exe" , StringComparison.OrdinalIgnoreCase)
164164
165- resolve [ " System " ; " mscorlib " ; " mscorlib.dll " ; " FSharp.Core " ; " FSharp.Core. dll" ; " Microsoft.SqlServer.Dmf. dll" ; " Microsoft.SqlServer.Dmf " ]
165+ let qual = if isFileName then r else try AssemblyName ( r ) .Name + " . dll" with _ -> r + " . dll"
166166
167- resolve [ " FSharp.Core, Version=4.4.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" ]
167+ for searchPath in searchPaths do
168+ try
169+ if not found then
170+ let trialPath = Path.Combine( searchPath, qual)
171+ if FileSystem.SafeExists( trialPath) then
172+ success trialPath
173+ with e -> logWarning " SR001" ( e.ToString())
174+
175+ #if ! RESHAPED_ MSBUILD
176+ try
177+ // Seach the GAC on Windows
178+ if not found && not isFileName && Environment.OSVersion.Platform = PlatformID.Win32NT then
179+ let n = AssemblyName( r)
180+ let netfx = System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory()
181+ let gac = Path.Combine( Path.GetDirectoryName( Path.GetDirectoryName( netfx.TrimEnd( '\\' ))), " assembly" )
182+ match n.Version, n.GetPublicKeyToken() with
183+ | null , _ | _, null ->
184+ let options =
185+ [ for gacdir in Directory.EnumerateDirectories( gac) do
186+ let assdir = Path.Combine( gacdir, n.Name)
187+ if Directory.Exists( assdir) then
188+ for tdir in Directory.EnumerateDirectories( assdir) do
189+ let trialPath = Path.Combine( tdir, qual)
190+ if FileSystem.SafeExists( trialPath) then
191+ yield trialPath ]
192+ //printfn "sorting GAC paths: %A" options
193+ options
194+ |> List.sort // puts latest version last
195+ |> List.tryLast
196+ |> function None -> () | Some p -> success p
197+
198+ | v, tok ->
199+ for gacdir in Directory.EnumerateDirectories( gac) do
200+ //printfn "searching GAC directory: %s" gacdir
201+ let assdir = Path.Combine( gacdir, n.Name)
202+ if Directory.Exists( assdir) then
203+ //printfn "searching GAC directory: %s" assdir
204+
205+ let tokText = String.concat " " [| for b in tok -> sprintf " %02x " b |]
206+ let verdir = Path.Combine( assdir, " v4.0_" + v.ToString()+ " __" + tokText)
207+ //printfn "searching GAC directory: %s" verdir
208+
209+ if Directory.Exists( verdir) then
210+ let trialPath = Path.Combine( verdir, qual)
211+ //printfn "searching GAC: %s" trialPath
212+ if FileSystem.SafeExists( trialPath) then
213+ success trialPath
214+ with e -> logWarning " SR001" ( e.ToString())
168215#endif
169216
217+ results.ToArray() }
218+
170219let GetDefaultResolver ( msbuildEnabled : bool , msbuildVersion : string option ) =
171- //let msbuildEnabled = msbuildEnabled && false
220+ #if RESHAPED_ MSBUILD
221+ ignore msbuildVersion
222+ ignore msbuildEnabled
223+ #else
224+ let msbuildEnabled = msbuildEnabled && false
225+ let msbuildVersion = defaultArg msbuildVersion " 12"
172226 let tryMSBuild v =
173- if msbuildEnabled then
174- // Detect if MSBuild v12 is on the machine, if so use the resolver from there
175- let mb = try System.Reflection.Assembly.Load( sprintf " Microsoft.Build.Framework, Version=%s .0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" v) |> Option.ofObj with _ -> None
176- let ass = mb |> Option.bind ( fun _ -> try System.Reflection.Assembly.Load( sprintf " FSharp.Compiler.Service.MSBuild.v%s " v) |> Option.ofObj with _ -> None)
227+ // Detect if MSBuild is on the machine, if so use the resolver from there
228+ let mb = try Assembly.Load( sprintf " Microsoft.Build.Framework, Version=%s .0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" v) |> Option.ofObj with _ -> None
229+ let ass = mb |> Option.bind ( fun _ -> try Assembly.Load( sprintf " FSharp.Compiler.Service.MSBuild.v%s " v) |> Option.ofObj with _ -> None)
177230 let ty = ass |> Option.bind ( fun ass -> ass.GetType( " Microsoft.FSharp.Compiler.MSBuildReferenceResolver" ) |> Option.ofObj)
178- let obj = ty |> Option.bind ( fun ty -> ty.InvokeMember( " get_Resolver" , System.Reflection. BindingFlags.Static ||| System.Reflection. BindingFlags.Public ||| System.Reflection. BindingFlags.InvokeMethod ||| System.Reflection. BindingFlags.NonPublic, null , null , [| |]) |> Option.ofObj)
231+ let obj = ty |> Option.bind ( fun ty -> ty.InvokeMember( " get_Resolver" , BindingFlags.Static ||| BindingFlags.Public ||| BindingFlags.InvokeMethod ||| BindingFlags.NonPublic, null , null , [| |]) |> Option.ofObj)
179232 let resolver = obj |> Option.bind ( fun obj -> match obj with :? Resolver as r -> Some r | _ -> None)
180233 resolver
181- else None
182- match tryMSBuild ( defaultArg msbuildVersion " 12" ) with
234+ match ( if msbuildEnabled then tryMSBuild msbuildVersion else None) with
183235 | Some r -> r
184236 | None ->
185237 //match tryMSBuild "15" with
@@ -188,7 +240,53 @@ let GetDefaultResolver(msbuildEnabled: bool, msbuildVersion: string option) =
188240 //match tryMSBuild "14" with
189241 //| Some r -> r
190242 //| None ->
191- match tryMSBuild " 12" with
243+ match ( if msbuildEnabled && msbuildVersion <> " 12 " then tryMSBuild " 12" else None ) with
192244 | Some r -> r
193245 | None ->
194- ScriptingNaiveResolver
246+ #endif
247+ SimulatedMSBuildResolver
248+
249+
250+ #if INTERACTIVE
251+ // Some manual testing
252+ SimulatedMSBuildResolver.DotNetFrameworkReferenceAssembliesRootDirectory
253+ SimulatedMSBuildResolver.HighestInstalledNetFrameworkVersion()
254+
255+ let fscoreDir =
256+ if System.Environment.OSVersion.Platform = System.PlatformID.Win32NT then // file references only valid on Windows
257+ let PF =
258+ match Environment.GetEnvironmentVariable( " ProgramFiles(x86)" ) with
259+ | null -> Environment.GetEnvironmentVariable( " ProgramFiles" ) // if PFx86 is null, then we are 32-bit and just get PF
260+ | s -> s
261+ PF + @" \Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\4.4.0.0"
262+ else
263+ System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory()
264+
265+ let resolve s =
266+ SimulatedMSBuildResolver.Resolve( ResolutionEnvironment.CompileTimeLike,[| for a in s -> ( a, " " ) |], " v4.5.1" , [ SimulatedMSBuildResolver.DotNetFrameworkReferenceAssembliesRootDirectory + @" \v4.5.1" ], " " , " " , fscoreDir,[],__ SOURCE_ DIRECTORY__, ignore, ( fun _ _ -> ()), ( fun _ _ -> ()))
267+
268+ // Resolve partial name to something on search path
269+ resolve [ " FSharp.Core" ]
270+
271+ // Resolve DLL name to something on search path
272+ resolve [ " FSharp.Core.dll" ]
273+
274+ // Resolve from reference assemblies
275+ resolve [ " System" ; " mscorlib" ; " mscorlib.dll" ]
276+
277+ // Resolve from Registry AssemblyFolders
278+ resolve [ " Microsoft.SqlServer.Dmf.dll" ; " Microsoft.SqlServer.Dmf" ]
279+
280+ // Resolve exact version of FSharp.Core
281+ resolve [ " FSharp.Core, Version=4.4.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" ]
282+
283+ // Resolve from GAC:
284+ resolve [ " EventViewer, Version=6.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" ]
285+
286+ // Resolve from GAC:
287+ resolve [ " EventViewer" ]
288+
289+ resolve [ " Microsoft.SharePoint.Client, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" ]
290+ resolve [ " Microsoft.SharePoint.Client, Version=16.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" ]
291+ #endif
292+
0 commit comments