diff --git a/.gitignore b/.gitignore index 89a796baf2..98da687d68 100644 --- a/.gitignore +++ b/.gitignore @@ -73,6 +73,8 @@ src/fsharp/FSharp.LanguageService.Compiler/pplex.fs src/fsharp/FSharp.LanguageService.Compiler/pppars.fs src/fsharp/FSharp.LanguageService.Compiler/pppars.fsi vsintegration/src/unittests/Unittests.fsi +tests/*FSharp_Failures.env +tests/*FSharp_Failures.lst tests/fsharpqa/Source/CodeGen/EmittedIL/StaticInit/StaticInit_Module01.dll tests/fsharpqa/Source/CodeGen/EmittedIL/StaticInit/StaticInit_Module01.pdb tests/XFSharpQA_Failures.log.* @@ -80,6 +82,8 @@ vsintegration/src/vs/FsPkgs/FSharp.Project/FS/FSharp.ProjectSystem.FSharp.fsi vsintegration/src/vs/FsPkgs/FSharp.Project/FS/ctofiles/ tests/fsharpqa/Source/CodeGen/EmittedIL/QueryExpressionStepping/Utils.dll tests/fsharpqa/Source/CodeGen/EmittedIL/ComputationExpressions/ComputationExprLibrary.dll +tests/fsharpqa/Source/*FSharpQA_Failures.env +tests/fsharpqa/Source/*FSharpQA_Failures.lst *.csproj.user *.sln.DotSettings.user *.ide diff --git a/DEVGUIDE.md b/DEVGUIDE.md index 5e9160f7a7..44301e6af1 100644 --- a/DEVGUIDE.md +++ b/DEVGUIDE.md @@ -131,7 +131,7 @@ Restart Visual Studio, it should now be running your freshly-built Visual F# IDE ### Notes on the build -1. The `update.cmd` script adds the built `FSharp.Core` to the GAC, adds required strong name validation skips, and NGens the compiler and libraries. This requires admin privileges. +1. The `update.cmd` script adds required strong name validation skips, and NGens the compiler and libraries. This requires admin privileges. 1. The compiler binaries produced are "private" and strong-named signed with a test key. 1. Some additional tools are required to build the compiler, notably `fslex.exe`, `fsyacc.exe`, `FSharp.PowerPack.Build.Tasks.dll`, `FsSrGen.exe`, `FSharp.SRGen.Build.Tasks.dll`, and the other tools found in the `lkg` directory. 1. The overall bootstrapping process executes as follows diff --git a/TESTGUIDE.md b/TESTGUIDE.md index a95c48258e..316f8cb75c 100644 --- a/TESTGUIDE.md +++ b/TESTGUIDE.md @@ -23,7 +23,7 @@ In order to run all of the tests, you will need to install * [Perl](http://www.perl.org/get.html) (ActiveState Perl 5.16.3 is known to work fine) -Perl must be included in the `%PATH%` for the below steps to work. It is also recommended that you run tests from an elevated command prompt, as there are a couple of test cases which modify the GAC, and this requires administrative privileges. +Perl must be included in the `%PATH%` for the below steps to work. It is also recommended that you run tests from an elevated command prompt, as there are a couple of test cases which require administrative privileges. Before running tests, make sure you have successfully built all required projects as specified in the 'Prepare For Tests' section of the [DEVGUIDE](DEVGUIDE.md). diff --git a/src/assemblyinfo/assemblyinfo.FSharp.Core.dll.fs b/src/assemblyinfo/assemblyinfo.FSharp.Core.dll.fs index c88d9d117b..c3ccc753f6 100644 --- a/src/assemblyinfo/assemblyinfo.FSharp.Core.dll.fs +++ b/src/assemblyinfo/assemblyinfo.FSharp.Core.dll.fs @@ -15,7 +15,7 @@ open System.Runtime.InteropServices #if PORTABLE [] -[] // ensure we replace any 4.0.30319.* or 4.0.31105.* versions in the GAC. These are the FileVersions for RTM VS2010 and SP1 VS2010 +[] #endif do() diff --git a/src/assemblyinfo/assemblyinfo.FSharp.Data.TypeProviders.dll.fs b/src/assemblyinfo/assemblyinfo.FSharp.Data.TypeProviders.dll.fs index f5a4f3d1ab..6cb03e6d37 100644 --- a/src/assemblyinfo/assemblyinfo.FSharp.Data.TypeProviders.dll.fs +++ b/src/assemblyinfo/assemblyinfo.FSharp.Data.TypeProviders.dll.fs @@ -17,7 +17,7 @@ do() [] [] #else -[] // ensure we replace any 4.0.30319.* or 4.0.31105.* versions in the GAC. These are the FileVersions for RTM VS2010 and SP1 VS2010 +[] [] [] #endif diff --git a/src/fsharp/CompileOps.fs b/src/fsharp/CompileOps.fs index 903298c120..cc67345ed5 100755 --- a/src/fsharp/CompileOps.fs +++ b/src/fsharp/CompileOps.fs @@ -2033,6 +2033,10 @@ type TcConfigBuilder = mutable emitDebugInfoInQuotations : bool mutable exename : string option + + // If true - the compiler will copy FSharp.Core.dll along the produced binaries + mutable copyFSharpCore : bool + /// When false FSI will lock referenced assemblies requiring process restart, false = disable Shadow Copy false (*default*) mutable shadowCopyReferences : bool } @@ -2172,6 +2176,7 @@ type TcConfigBuilder = sqmSessionStartedTime = System.DateTime.Now.Ticks emitDebugInfoInQuotations = false exename = None + copyFSharpCore = true shadowCopyReferences = false } @@ -2638,6 +2643,7 @@ type TcConfig private (data : TcConfigBuilder,validate:bool) = member x.sqmSessionGuid = data.sqmSessionGuid member x.sqmNumOfSourceFiles = data.sqmNumOfSourceFiles member x.sqmSessionStartedTime = data.sqmSessionStartedTime + member x.copyFSharpCore = data.copyFSharpCore member x.shadowCopyReferences = data.shadowCopyReferences static member Create(builder,validate) = diff --git a/src/fsharp/CompileOps.fsi b/src/fsharp/CompileOps.fsi index a3602b3530..e8e0212366 100755 --- a/src/fsharp/CompileOps.fsi +++ b/src/fsharp/CompileOps.fsi @@ -351,6 +351,7 @@ type TcConfigBuilder = sqmSessionStartedTime : int64 mutable emitDebugInfoInQuotations : bool mutable exename : string option + mutable copyFSharpCore : bool mutable shadowCopyReferences : bool } @@ -508,6 +509,7 @@ type TcConfig = member sqmSessionGuid : System.Guid option member sqmNumOfSourceFiles : int member sqmSessionStartedTime : int64 + member copyFSharpCore : bool member shadowCopyReferences : bool static member Create : TcConfigBuilder * validate: bool -> TcConfig diff --git a/src/fsharp/CompileOptions.fs b/src/fsharp/CompileOptions.fs index 1e2fe37a9f..5a1888a0f0 100644 --- a/src/fsharp/CompileOptions.fs +++ b/src/fsharp/CompileOptions.fs @@ -513,6 +513,7 @@ let PrintOptionInfo (tcConfigB:TcConfigBuilder) = printfn " debuginfo . . . . . . : %+A" tcConfigB.debuginfo printfn " resolutionEnvironment : %+A" tcConfigB.resolutionEnvironment printfn " product . . . . . . . : %+A" tcConfigB.productNameForBannerText + printfn " copyFSharpCore . . . . : %+A" tcConfigB.copyFSharpCore tcConfigB.includes |> List.sort |> List.iter (printfn " include . . . . . . . : %A") @@ -611,6 +612,8 @@ let outputFileFlagsFsc (tcConfigB : TcConfigBuilder) = CompilerOption("sig", tagFile, OptionString (setSignatureFile tcConfigB), None, Some (FSComp.SR.optsSig())); + + CompilerOption("nocopyfsharpcore", tagNone, OptionUnit (fun () -> tcConfigB.copyFSharpCore <- false), None, Some (FSComp.SR.optsNoCopyFsharpCore())); ] diff --git a/src/fsharp/FSComp.txt b/src/fsharp/FSComp.txt index 8e15d8dc4e..ab16418c8b 100644 --- a/src/fsharp/FSComp.txt +++ b/src/fsharp/FSComp.txt @@ -877,6 +877,7 @@ optsUseHighEntropyVA,"Enable high-entropy ASLR" optsSubSystemVersion,"Specify subsystem version of this assembly" optsTargetProfile,"Specify target framework profile of this assembly. Valid values are mscorlib or netcore. Default - mscorlib" optsEmitDebugInfoInQuotations,"Emit debug information in quotations" +optsNoCopyFsharpCore,"Don't copy FSharp.Core.dll along the produced binaries" 1051,optsInvalidSubSystemVersion,"Invalid version '%s' for '--subsystemversion'. The version must be 4.00 or greater." 1052,optsInvalidTargetProfile,"Invalid value '%s' for '--targetprofile', valid values are 'mscorlib' or 'netcore'." typeInfoFullName,"Full name" @@ -1269,3 +1270,4 @@ estApplyStaticArgumentsForMethodNotImplemented,"A type provider implemented GetS 3193,optsInvalidResponseFile,"Invalid response file '%s' ( '%s' )" 3194,optsResponseFileNotFound,"Response file '%s' not found in '%s'" 3195,optsResponseFileNameInvalid,"Response file name '%s' is empty, contains invalid characters, has a drive specification without an absolute path, or is too long" +3196,fsharpCoreNotFoundToBeCopied,"Cannot find FSharp.Core.dll in compiler's directory" diff --git a/src/fsharp/ReferenceResolution.fs b/src/fsharp/ReferenceResolution.fs index e8c76b9464..9f8c62c492 100644 --- a/src/fsharp/ReferenceResolution.fs +++ b/src/fsharp/ReferenceResolution.fs @@ -277,8 +277,8 @@ module internal MSBuildResolver = // These are search paths for runtime-like or scripting resolution. GAC searching is present. yield! rawFileNamePath // Quick-resolve straight to filename first yield! explicitIncludeDirs // From -I, #I - yield implicitIncludeDir // Usually the project directory yield fsharpCoreExplicitDirOrFSharpBinariesDir // Location of explicit reference to FSharp.Core, otherwise location of fsc.exe + yield implicitIncludeDir // Usually the project directory yield "{TargetFrameworkDirectory}" yield registry yield "{AssemblyFolders}" @@ -290,8 +290,8 @@ module internal MSBuildResolver = yield "{TargetFrameworkDirectory}" yield! rawFileNamePath // Quick-resolve straight to filename first yield! explicitIncludeDirs // From -I, #I - yield implicitIncludeDir // Usually the project directory yield fsharpCoreExplicitDirOrFSharpBinariesDir // Location of explicit reference to FSharp.Core, otherwise location of fsc.exe + yield implicitIncludeDir // Usually the project directory yield registry yield "{AssemblyFolders}" yield outputDirectory diff --git a/src/fsharp/fsc.fs b/src/fsharp/fsc.fs index f098495b3a..c302315f05 100755 --- a/src/fsharp/fsc.fs +++ b/src/fsharp/fsc.fs @@ -1781,7 +1781,27 @@ let ValidateKeySigningAttributes (tcConfig : TcConfig, tcGlobals, topAttrs) = | None -> tcConfig.container SigningInfo (delaysign,signer,container) - + +// If the --nocopyfsharpcore switch is not specified, this will: +// 1) Look into the referenced assemblies, if FSharp.Core.dll is specified, it will copy it to output directory. +// 2) If not, but FSharp.Core.dll exists beside the compiler binaries, it will copy it to output directory. +// 3) If not, it will produce an error. +let copyFSharpCore(outFile: string, referencedDlls: AssemblyReference list) = + let outDir = Path.GetDirectoryName(outFile) + let fsharpCoreAssemblyName = GetFSharpCoreLibraryName() + ".dll" + let fsharpCoreDestinationPath = Path.Combine(outDir, fsharpCoreAssemblyName) + + if not (File.Exists(fsharpCoreDestinationPath)) then + match referencedDlls |> Seq.tryFind (fun dll -> String.Equals(Path.GetFileName(dll.Text), fsharpCoreAssemblyName, StringComparison.CurrentCultureIgnoreCase)) with + | Some referencedFsharpCoreDll -> File.Copy(referencedFsharpCoreDll.Text, fsharpCoreDestinationPath) + | None -> + let compilerLocation = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + let compilerFsharpCoreDllPath = Path.Combine(compilerLocation, fsharpCoreAssemblyName) + if File.Exists(compilerFsharpCoreDllPath) then + File.Copy(compilerFsharpCoreDllPath, fsharpCoreDestinationPath) + else + errorR(Error(FSComp.SR.fsharpCoreNotFoundToBeCopied(), rangeCmdArgs)) + //---------------------------------------------------------------------------- // main - split up to make sure that we can GC the // dead data at the end of each phase. We explicitly communicate arguments @@ -2001,10 +2021,14 @@ let main4 (Args (tcConfig, errorLogger: ErrorLogger, ilGlobals, ilxMainModule, o FileWriter.EmitIL (tcConfig, ilGlobals, errorLogger, outfile, pdbfile, ilxMainModule, signingInfo, exiter) AbortOnError(errorLogger, tcConfig, exiter) + if tcConfig.showLoadedAssemblies then for a in System.AppDomain.CurrentDomain.GetAssemblies() do dprintfn "%s" a.FullName + if tcConfig.copyFSharpCore then + copyFSharpCore(outfile, tcConfig.referencedDLLs) + SqmLoggerWithConfig tcConfig errorLogger.ErrorNumbers errorLogger.WarningNumbers ReportTime tcConfig "Exiting" diff --git a/src/update.cmd b/src/update.cmd index 088073d6c7..e67434cd71 100644 --- a/src/update.cmd +++ b/src/update.cmd @@ -11,7 +11,7 @@ if /i "%1" == "release" goto :ok if /i "%1" == "vsdebug" goto :ok if /i "%1" == "vsrelease" goto :ok -echo GACs built binaries, adds required strong name verification skipping, and optionally NGens built binaries +echo adding required strong name verification skipping, and NGening built binaries echo Usage: echo update.cmd debug [-ngen] echo update.cmd release [-ngen] @@ -35,7 +35,6 @@ if "%WINSDKNETFXTOOLS%"=="" FOR /F "tokens=2* delims= " %%A IN ('%REGEXE32BIT% if "%WINSDKNETFXTOOLS%"=="" FOR /F "tokens=2* delims= " %%A IN ('%REGEXE32BIT% QUERY "HKLM\Software\Microsoft\Microsoft SDKs\Windows\v7.1\WinSDK-NetFx40Tools" /v InstallationFolder') DO SET WINSDKNETFXTOOLS=%%B if "%WINSDKNETFXTOOLS%"=="" FOR /F "tokens=2* delims= " %%A IN ('%REGEXE32BIT% QUERY "HKLM\Software\Microsoft\Microsoft SDKs\Windows\v7.0A\WinSDK-NetFx40Tools" /v InstallationFolder') DO SET WINSDKNETFXTOOLS=%%B -set GACUTIL="%WINSDKNETFXTOOLS%gacutil.exe" set SN32="%WINSDKNETFXTOOLS%sn.exe" set SN64="%WINSDKNETFXTOOLS%x64\sn.exe" set NGEN32=%windir%\Microsoft.NET\Framework\v4.0.30319\ngen.exe @@ -80,9 +79,6 @@ if /i "%PROCESSOR_ARCHITECTURE%"=="AMD64" ( %SN64% -Vr Salsa,b03f5f7f11d50a3a ) -rem Only GACing FSharp.Core for now -%GACUTIL% /if %BINDIR%\FSharp.Core.dll - rem NGen fsc, fsi, fsiAnyCpu, and FSharp.Build.dll if /i not "%2"=="-ngen" goto :donengen diff --git a/src/update.fs b/src/update.fs index 9ba090f5bc..bcf3d3cb2a 100644 --- a/src/update.fs +++ b/src/update.fs @@ -36,7 +36,7 @@ let updateCmd envVars args = processor { // if /i "%1" == "release" goto :ok ignore "already validated input" - // echo GACs built binaries, adds required strong name verification skipping, and optionally NGens built binaries + // echo adding required strong name verification skipping, and NGening built binaries // echo Usage: // echo update.cmd debug [-ngen] // echo update.cmd release [-ngen] @@ -82,8 +82,6 @@ let updateCmd envVars args = processor { let WINSDKNETFXTOOLS = match allWINSDKNETFXTOOLS |> Seq.tryPick id with Some sdk -> sdk | None -> "" - // set GACUTIL="%WINSDKNETFXTOOLS%gacutil.exe" - let GACUTIL = WINSDKNETFXTOOLS/"gacutil.exe" // set SN32="%WINSDKNETFXTOOLS%sn.exe" let SN32 = WINSDKNETFXTOOLS/"sn.exe" // set SN64="%WINSDKNETFXTOOLS%x64\sn.exe" @@ -95,7 +93,6 @@ let updateCmd envVars args = processor { let checkResult = function CmdResult.ErrorLevel err -> Failure (sprintf "ERRORLEVEL %d" err) | CmdResult.Success -> Success () - let gacutil flags = Commands.gacutil exec GACUTIL flags >> checkResult let ngen32 = Commands.ngen exec NGEN32 >> checkResult let ngen64 = Commands.ngen exec NGEN64 >> checkResult let sn32 = exec SN32 >> checkResult @@ -160,10 +157,6 @@ let updateCmd envVars args = processor { (fun () -> Success ()) //) - // rem Only GACing FSharp.Core for now - // %GACUTIL% /if %BINDIR%\FSharp.Core.dll - do! gacutil "/if" (binDir/"FSharp.Core.dll") - // rem NGen fsc, fsi, fsiAnyCpu, and FSharp.Build.dll // if /i not "%2"=="-ngen" goto :donengen diff --git a/tests/RunTests.cmd b/tests/RunTests.cmd index e39bc9a477..43835bc11a 100644 --- a/tests/RunTests.cmd +++ b/tests/RunTests.cmd @@ -182,8 +182,6 @@ set PATH=%PATH%;%WINSDKNETFXTOOLS% IF NOT DEFINED SNEXE32 IF EXIST "%WINSDKNETFXTOOLS%sn.exe" set SNEXE32=%WINSDKNETFXTOOLS%sn.exe IF NOT DEFINED SNEXE64 IF EXIST "%WINSDKNETFXTOOLS%x64\sn.exe" set SNEXE64=%WINSDKNETFXTOOLS%x64\sn.exe -IF NOT DEFINED GACUTILEXE32 IF EXIST "%WINSDKNETFXTOOLS%gacutil.exe" set GACUTILEXE32=%WINSDKNETFXTOOLS%gacutil.exe -IF NOT DEFINED GACUTILEXE64 IF EXIST "%WINSDKNETFXTOOLS%x64\gacutil.exe" set GACUTILEXE64=%WINSDKNETFXTOOLS%x64\gacutil.exe set FSC=%FSCBINPATH%\fsc.exe set PATH=%FSCBINPATH%;%PATH% diff --git a/tests/config.bat b/tests/config.bat index 8d047c19f1..0868e704b2 100644 --- a/tests/config.bat +++ b/tests/config.bat @@ -40,7 +40,6 @@ if not defined CSC set CSC=csc.exe %csc_flags% REM SDK Dependencires. if not defined ILDASM set ILDASM=ildasm.exe -if not defined GACUTIL set GACUTIL=gacutil.exe if not defined PEVERIFY set PEVERIFY=peverify.exe if not defined RESGEN set RESGEN=resgen.exe @@ -75,7 +74,6 @@ set fsc_flags=%fsc_flags% set CLR_SUPPORTS_GENERICS=true set ILDASM=%ILDASM% -set GACUTIL=%GACUTIL% set CLR_SUPPORTS_WINFORMS=true set CLR_SUPPORTS_SYSTEM_WEB=true @@ -148,7 +146,6 @@ REM == The logic here is: pick the latest msbuild REM == If we are testing against NDP4.0, then don't try msbuild 3.5 REM == IF NOT "%CORSDK%"=="" IF EXIST "%CORSDK%\ildasm.exe" SET ILDASM=%CORSDK%\ildasm.exe -IF NOT "%CORSDK%"=="" IF EXIST "%CORSDK%\gacutil.exe" SET GACUTIL=%CORSDK%\gacutil.exe IF NOT "%CORSDK%"=="" IF EXIST "%CORSDK%\peverify.exe" SET PEVERIFY=%CORSDK%\peverify.exe IF NOT "%CORSDK%"=="" IF EXIST "%CORSDK%\resgen.exe" SET RESGEN=%CORSDK%\resgen.exe IF NOT "%CORSDK%"=="" IF NOT EXIST "%RESGEN%" IF EXIST "%CORSDK%\..\resgen.exe" SET RESGEN=%CORSDK%\..\resgen.exe @@ -218,7 +215,6 @@ echo FSDATATPPATH =%FSDATATPPATH% echo FSDIFF =%FSDIFF% echo FSI =%FSI% echo fsi_flags =%fsi_flags% -echo GACUTIL =%GACUTIL% echo ILDASM =%ILDASM% echo INSTALL_SKU =%INSTALL_SKU% echo MSBUILDTOOLSPATH =%MSBuildToolsPath% diff --git a/tests/fsharp/typecheck/sigs/neg46.bsl b/tests/fsharp/typecheck/sigs/neg46.bsl index ca1733f564..1bdf9fbc95 100644 --- a/tests/fsharp/typecheck/sigs/neg46.bsl +++ b/tests/fsharp/typecheck/sigs/neg46.bsl @@ -23,7 +23,7 @@ neg46.fs(48,8,48,34): typecheck error FS0912: This declaration element is not pe neg46.fs(52,8,52,39): typecheck error FS0912: This declaration element is not permitted in an augmentation -neg46.fs(56,8,56,11): typecheck error FS3191: Constructors are not permitted as extension members - they must be defined as part of the original definition of the type +neg46.fs(56,8,56,11): typecheck error FS3192: Constructors are not permitted as extension members - they must be defined as part of the original definition of the type neg46.fs(56,8,56,11): typecheck error FS0871: Constructors cannot be defined for this type diff --git a/tests/fsharpqa/Source/CompilerOptions/fsc/help/help40.437.1033.bsl b/tests/fsharpqa/Source/CompilerOptions/fsc/help/help40.437.1033.bsl index d33d914dcc..7ed059b54b 100644 --- a/tests/fsharpqa/Source/CompilerOptions/fsc/help/help40.437.1033.bsl +++ b/tests/fsharpqa/Source/CompilerOptions/fsc/help/help40.437.1033.bsl @@ -26,6 +26,8 @@ Copyright (c) Microsoft Corporation. All Rights Reserved. containing F#-specific metadata --sig: Print the inferred interface of the assembly to a file +--nocopyfsharpcore Don't copy FSharp.Core.dll along the produced + binaries - INPUT FILES - diff --git a/vsintegration/update-vsintegration.cmd b/vsintegration/update-vsintegration.cmd index 5292135e1d..dca5f63a13 100644 --- a/vsintegration/update-vsintegration.cmd +++ b/vsintegration/update-vsintegration.cmd @@ -31,7 +31,6 @@ if "%WINSDKNETFXTOOLS%"=="" FOR /F "tokens=2* delims= " %%A IN ('%REGEXE32BIT% if "%WINSDKNETFXTOOLS%"=="" FOR /F "tokens=2* delims= " %%A IN ('%REGEXE32BIT% QUERY "HKLM\Software\Microsoft\Microsoft SDKs\Windows\v7.1\WinSDK-NetFx40Tools" /v InstallationFolder') DO SET WINSDKNETFXTOOLS=%%B if "%WINSDKNETFXTOOLS%"=="" FOR /F "tokens=2* delims= " %%A IN ('%REGEXE32BIT% QUERY "HKLM\Software\Microsoft\Microsoft SDKs\Windows\v7.0A\WinSDK-NetFx40Tools" /v InstallationFolder') DO SET WINSDKNETFXTOOLS=%%B -set GACUTIL="%WINSDKNETFXTOOLS%gacutil.exe" set SN32="%WINSDKNETFXTOOLS%sn.exe" set SN64="%WINSDKNETFXTOOLS%x64\sn.exe" set NGEN32=%windir%\Microsoft.NET\Framework\v4.0.30319\ngen.exe @@ -140,8 +139,14 @@ if /i "%PROCESSOR_ARCHITECTURE%"=="AMD64" ( %SN64% -Vr Salsa,b03f5f7f11d50a3a ) -%GACUTIL% /if %BINDIR%\FSharp.Compiler.Interactive.Settings.dll -%GACUTIL% /if %BINDIR%\FSharp.Compiler.Server.Shared.dll +if exist "%ProgramFiles(x86)%\Microsoft Visual Studio %VisualStudioVersion%\Common7\IDE\PrivateAssemblies" ( + copy /y %BINDIR%\FSharp.Compiler.Server.Shared.dll "%ProgramFiles(x86)%\Microsoft Visual Studio %VisualStudioVersion%\Common7\IDE\PrivateAssemblies\FSharp.Compiler.Server.Shared.dll" + copy /y %BINDIR%\FSharp.Compiler.Interactive.Settings.dll "%ProgramFiles(x86)%\Microsoft Visual Studio %VisualStudioVersion%\Common7\IDE\PrivateAssemblies\FSharp.Compiler.Interactive.Settings.dll" +) +if exist "%ProgramFiles%\Microsoft Visual Studio %VisualStudioVersion%\Common7\IDE\PrivateAssemblies" ( + copy /y %BINDIR%\FSharp.Compiler.Server.Shared.dll "%ProgramFiles%\Microsoft Visual Studio %VisualStudioVersion%\Common7\IDE\PrivateAssemblies\FSharp.Compiler.Server.Shared.dll" + copy /y %BINDIR%\FSharp.Compiler.Interactive.Settings.dll "%ProgramFiles%\Microsoft Visual Studio %VisualStudioVersion%\Common7\IDE\PrivateAssemblies\FSharp.Compiler.Interactive.Settings.dll" +) rem NGen fsc, fsi, fsiAnyCpu, and FSharp.Build.dll