diff --git a/vsintegration/update-vsintegration.cmd b/vsintegration/update-vsintegration.cmd
index e7d1d85eaa5..9dcb36f92d5 100644
--- a/vsintegration/update-vsintegration.cmd
+++ b/vsintegration/update-vsintegration.cmd
@@ -3,30 +3,148 @@
@rem See License.txt in the project root for license information.
@rem ===========================================================================================================
-rem @echo off
-setlocal
+@rem Notes/instructions for modifications:
+@rem
+@rem * Do not use "::" for comments, as the line will be parsed and can create spurious
+@rem errors, i.e. if it contains variables, "|" or ">" characters, esp. within "IF"
+@rem and "FOR" compound statements
+@rem
+@rem * The coloring method uses the colors from color /h through a hacky trick with findstr.
+@rem Only use filename-safe characters if you use CALL :colorEcho
+@rem
+@rem * Parts of this batch file require administrator permission. If such permissions aren't
+@rem available, a warning will be issued and relevant parts will not be executed.
+@rem
+@rem * Currently, only one paramter is parsed and combinations are not possible
+@rem
+@rem * Installation of F# FSC compiler and FSI are done in the SHARED SDK directory. Henceforth
+@rem each installation of Visual Studio 2017 will use the updated FSC.exe and the commandline
+@rem FSI.exe. The in-product VS FSI plugin, syntax highlighting and IntelliSense must be
+@rem installed through VSIXInstaller.exe debug\net40\bin\VisualFSharpOpenSource.vsix
+@rem
+@rem This procedure needs to be changed once F# supports multiple side-by-side installations
+@rem at which point everything will go through VSIXInstaller.exe
-if /i "%1" == "debug" goto :ok
-if /i "%1" == "release" goto :ok
+@echo off
+setlocal EnableDelayedExpansion
-echo Clobbers existing Visual Studio installation of F# bits
-echo Usage:
-echo update-vsintegration.cmd debug
-echo update-vsintegration.cmd release
-exit /b 1
+rem Count errors, warnings and succesful copies
+set ERRORCOUNT=0
+set WARNCOUNT=0
+set COPYCOUNT=0
+
+rem Enable colors, but can ONLY BE USED WITH PRINTING LINES THAT FIT IN A FILENAME!
+for /F "tokens=1,2 delims=#" %%a in ('"prompt #$H#$E# & echo on & for %%b in (1) do rem"') do (
+ set "DEL=%%a"
+)
+
+if /i "%1" == "debug" (
+ set ACTION=debug
+ set DEPLOY=yes
+ set BINDIR=%~dp0..\%1\net40\bin
+ goto :ok
+)
+if /i "%1" == "release" (
+ set ACTION=release
+ set DEPLOY=yes
+ set BINDIR=%~dp0..\%1\net40\bin
+ goto :ok
+)
+if /i "%1" == "restore" (
+ set ACTION=restore
+ set DEPLOY=no
+ set BINDIR=%~dp0..\%1
+ goto :ok
+)
+if /i "%1" == "backup" (
+ set ACTION=backup
+ set DEPLOY=no
+ set BINDIR=%~dp0..\restore
+ goto :ok
+)
+
+set GOTOHELP=yes
:ok
-set BINDIR=%~dp0..\%1\net40\bin
+set RESTOREDIR=%~dp0..\restore
set TOPDIR=%~dp0..
+rem By using a token that does not exist in paths, this will resolve any ".." and "." in the path, even if path contains spaces
+FOR /F "tokens=*" %%I IN ("%RESTOREDIR%") DO set RESTOREDIR=%%~fI
+FOR /F "tokens=*" %%I IN ("%BINDIR%") DO set BINDIR=%%~fI
+FOR /F "tokens=*" %%I IN ("%TOPDIR%") DO set TOPDIR=%%~fI
+
+if /i "%GOTOHELP%" == "yes" goto :help
+GOTO :start
+
+
+:help
+
+echo.
+echo Installs or restores F# SDK bits, which applies system-wide to all Visual Studio
+echo 2017 installations. After running this, each project targeting F# 4.1 will use
+echo your locally built FSC.exe. It will not update other F# tools, see remarks below.
+echo.
+echo Requires Administrator privileges for removing/restoring strong-naming.
+echo.
+echo Syntax: %0 [debug^|release^|restore^|backup]
+echo.
+echo debug integrates debug builds of FSC, FSI ^& tools
+echo release integrates release builds of FSC, FSI ^& tools
+echo restore restores original SDK from an earlier backup
+echo backup backups the files that would be overwritten, does not deploy anything
+echo.
+echo Paths used:
+echo.
+echo Root location: %TOPDIR%
+echo Debug bin location: %TOPDIR%\debug\net40\bin
+echo Release bin location: %TOPDIR%\release\net40\bin
+echo Backup location: %RESTOREDIR%
+echo.
+echo Remarks:
+echo.
+echo This script should only be run after build.cmd has completed successfully.
+echo.
+echo Clearing the git repository may clear the backup directory. To be on the safe
+echo side, you should place a copy of the backup dir outside of the git repo.
+echo.
+echo This batch script will only update the relevant SDK bits, and remove or restore
+echo strong-naming automatically. It is recommended that you also update the F# Tools
+echo by running the following two commands after a build of "build vs" or
+echo "build vs debug" has completed. More instructions in DEVGUIDE.md in the root.
+echo.
+echo For Release builds:
+echo.
+echo ^> VSIXInstaller.exe /u:"VisualFSharp"
+echo ^> VSIXInstaller.exe release\net40\bin\VisualFSharpOpenSource.vsix
+echo.
+echo For Debug builds:
+echo.
+echo ^> VSIXInstaller.exe /u:"VisualFSharp"
+echo ^> VSIXInstaller.exe debug\net40\bin\VisualFSharpOpenSource.vsix
+echo.
+
+exit /b 1
+
+:start
+
+echo.
+if "%DEPLOY%" == "yes" echo Starting deployment of %ACTION% bits.
+if not "%DEPLOY%" == "yes" echo Starting %ACTION%
+echo.
+
+rem This check whether we're started with administrator rights
+CALL :checkPrequisites
+
if /i "%PROCESSOR_ARCHITECTURE%"=="x86" set X86_PROGRAMFILES=%ProgramFiles%
if /I "%PROCESSOR_ARCHITECTURE%"=="AMD64" set X86_PROGRAMFILES=%ProgramFiles(x86)%
set REGEXE32BIT=reg.exe
if not "%OSARCH%"=="x86" set REGEXE32BIT=%WINDIR%\syswow64\reg.exe
-::See https://stackoverflow.com/a/17113667/111575 on 2^>NUL for suppressing the error "ERROR: The system was unable to find the specified registry key or value." from reg.exe, this fixes #3619
+rem See https://stackoverflow.com/a/17113667/111575 on 2^>NUL for suppressing the error "ERROR: The system was unable to find the specified registry key or value." from reg.exe, this fixes #3619
+rem The delims are a TAB and a SPACE, do not normalize it!
FOR /F "tokens=2* delims= " %%A IN ('%REGEXE32BIT% QUERY "HKLM\Software\WOW6432Node\Microsoft\Microsoft SDKs\NETFXSDK\4.6.2\WinSDK-NetFx40Tools" /v InstallationFolder 2^>NUL') DO SET WINSDKNETFXTOOLS=%%B
if "%WINSDKNETFXTOOLS%"=="" FOR /F "tokens=2* delims= " %%A IN ('%REGEXE32BIT% QUERY "HKLM\Software\WOW6432Node\Microsoft\Microsoft SDKs\NETFXSDK\4.6.1\WinSDK-NetFx40Tools" /v InstallationFolder 2^>NUL') DO SET WINSDKNETFXTOOLS=%%B
if "%WINSDKNETFXTOOLS%"=="" FOR /F "tokens=2* delims= " %%A IN ('%REGEXE32BIT% QUERY "HKLM\Software\Microsoft\Microsoft SDKs\NETFXSDK\4.6\WinSDK-NetFx40Tools" /v InstallationFolder 2^>NUL') DO SET WINSDKNETFXTOOLS=%%B
@@ -43,112 +161,510 @@ set NGEN64=%windir%\Microsoft.NET\Framework64\v4.0.30319\ngen.exe
set FSHARPVERSION=4.1
set FSHARPVERSION2=41
+rem The various locations of the SDK and tools
+
+rem SDK path, will be created if it doesn't exist
set COMPILERSDKPATH=%X86_PROGRAMFILES%\Microsoft SDKs\F#\%FSHARPVERSION%\Framework\v4.0
-mkdir "%COMPILERSDKPATH%"
-copy /y "%BINDIR%\fsc.exe" "%COMPILERSDKPATH%"
-copy /y "%BINDIR%\fsc.exe.config" "%COMPILERSDKPATH%"
-copy /y "%BINDIR%\FSharp.Build.dll" "%COMPILERSDKPATH%"
-copy /y "%BINDIR%\FSharp.Compiler.Private.dll" "%COMPILERSDKPATH%"
-copy /y "%BINDIR%\FSharp.Compiler.Interactive.Settings.dll" "%COMPILERSDKPATH%"
-copy /y "%BINDIR%\fsi.exe" "%COMPILERSDKPATH%"
-copy /y "%BINDIR%\fsi.exe.config" "%COMPILERSDKPATH%"
-copy /y "%BINDIR%\fsiAnyCpu.exe" "%COMPILERSDKPATH%"
-copy /y "%BINDIR%\fsiAnyCpu.exe.config" "%COMPILERSDKPATH%"
-copy /y "%BINDIR%\Microsoft.FSharp.Targets" "%COMPILERSDKPATH%"
-copy /y "%BINDIR%\Microsoft.Portable.FSharp.Targets" "%COMPILERSDKPATH%"
-copy /y "%BINDIR%\Microsoft.FSharp.NetSdk.props" "%COMPILERSDKPATH%"
-copy /y "%BINDIR%\Microsoft.FSharp.NetSdk.targets" "%COMPILERSDKPATH%"
-copy /y "%TOPDIR%\vsintegration\src\SupportedRuntimes\SupportedRuntimes.xml" "%COMPILERSDKPATH%"
+rem Main assemblies path, will be created if it doesn't exist
set COMPILERMAINASSEMBLIESPATH=%X86_PROGRAMFILES%\Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\4.%FSHARPVERSION%.0
-mkdir "%COMPILERMAINASSEMBLIESPATH%"
-copy /y "%BINDIR%\FSharp.Core.dll" "%COMPILERMAINASSEMBLIESPATH%"
-copy /y "%BINDIR%\FSharp.Core.optdata" "%COMPILERMAINASSEMBLIESPATH%"
-copy /y "%BINDIR%\FSharp.Core.sigdata" "%COMPILERMAINASSEMBLIESPATH%"
-copy /y "%BINDIR%\FSharp.Core.xml" "%COMPILERMAINASSEMBLIESPATH%"
+rem The .NET Core 3.7 assemblies path, will be created if it doesn't exist
set COMPILER7ASSEMBLIESPATH=%X86_PROGRAMFILES%\Reference Assemblies\Microsoft\FSharp\.NETCore\3.7.%FSHARPVERSION2%.0
-mkdir "%COMPILER7ASSEMBLIESPATH%"
-copy /y "%BINDIR%\..\..\portable7\bin\FSharp.Core.dll" "%COMPILER7ASSEMBLIESPATH%"
-copy /y "%BINDIR%\..\..\portable7\bin\FSharp.Core.optdata" "%COMPILER7ASSEMBLIESPATH%"
-copy /y "%BINDIR%\..\..\portable7\bin\FSharp.Core.sigdata" "%COMPILER7ASSEMBLIESPATH%"
-copy /y "%BINDIR%\..\..\portable7\bin\FSharp.Core.xml" "%COMPILER7ASSEMBLIESPATH%"
+rem The .NET Core 3.78 assemblies path, will be created if it doesn't exist
set COMPILER78ASSEMBLIESPATH=%X86_PROGRAMFILES%\Reference Assemblies\Microsoft\FSharp\.NETCore\3.78.%FSHARPVERSION2%.0
-mkdir "%COMPILER78ASSEMBLIESPATH%"
-copy /y "%BINDIR%\..\..\portable78\bin\FSharp.Core.dll" "%COMPILER78ASSEMBLIESPATH%"
-copy /y "%BINDIR%\..\..\portable78\bin\FSharp.Core.optdata" "%COMPILER78ASSEMBLIESPATH%"
-copy /y "%BINDIR%\..\..\portable78\bin\FSharp.Core.sigdata" "%COMPILER78ASSEMBLIESPATH%"
-copy /y "%BINDIR%\..\..\portable78\bin\FSharp.Core.xml" "%COMPILER78ASSEMBLIESPATH%"
+rem The .NET Core 3.259 assemblies path, will be created if it doesn't exist
set COMPILER259ASSEMBLIESPATH=%X86_PROGRAMFILES%\Reference Assemblies\Microsoft\FSharp\.NETCore\3.259.%FSHARPVERSION2%.0
-mkdir "%COMPILER259ASSEMBLIESPATH%"
-copy /y "%BINDIR%\..\..\portable259\bin\FSharp.Core.dll" "%COMPILER259ASSEMBLIESPATH%"
-copy /y "%BINDIR%\..\..\portable259\bin\FSharp.Core.optdata" "%COMPILER259ASSEMBLIESPATH%"
-copy /y "%BINDIR%\..\..\portable259\bin\FSharp.Core.sigdata" "%COMPILER259ASSEMBLIESPATH%"
-copy /y "%BINDIR%\..\..\portable259\bin\FSharp.Core.xml" "%COMPILER259ASSEMBLIESPATH%"
+rem The .NET Portable 3.47 assemblies path, will be created if it doesn't exist
set COMPILER47ASSEMBLIESPATH=%X86_PROGRAMFILES%\Reference Assemblies\Microsoft\FSharp\.NETPortable\3.47.%FSHARPVERSION2%.0
-mkdir "%COMPILER47ASSEMBLIESPATH%"
-copy /y "%BINDIR%\..\..\portable47\bin\FSharp.Core.dll" "%COMPILER47ASSEMBLIESPATH%"
-copy /y "%BINDIR%\..\..\portable47\bin\FSharp.Core.optdata" "%COMPILER47ASSEMBLIESPATH%"
-copy /y "%BINDIR%\..\..\portable47\bin\FSharp.Core.sigdata" "%COMPILER47ASSEMBLIESPATH%"
-copy /y "%BINDIR%\..\..\portable47\bin\FSharp.Core.xml" "%COMPILER47ASSEMBLIESPATH%"
+rem Try to create target and backup folders, if needed
+set RESTOREBASE=%RESTOREDIR%
+
+rem Only create backup dirs if we are backupping or restoring
+rem (in the latter case, the directories should already be there, but if not, it prevents errors later on)
+if "!DEPLOY!" == "no" (
+ CALL :tryCreateFolder "!RESTOREBASE!\compiler_sdk"
+ CALL :tryCreateFolder "!RESTOREBASE!\main_assemblies"
+ CALL :tryCreateFolder "!RESTOREBASE!\profile_7"
+ CALL :tryCreateFolder "!RESTOREBASE!\profile_78"
+ CALL :tryCreateFolder "!RESTOREBASE!\profile_259"
+ CALL :tryCreateFolder "!RESTOREBASE!\profile_47"
+)
+CALL :tryCreateFolder "!COMPILERSDKPATH!"
+CALL :tryCreateFolder "!COMPILERMAINASSEMBLIESPATH!"
+CALL :tryCreateFolder "!COMPILER7ASSEMBLIESPATH!" &
+CALL :tryCreateFolder "!COMPILER78ASSEMBLIESPATH!"
+CALL :tryCreateFolder "!COMPILER259ASSEMBLIESPATH!"
+CALL :tryCreateFolder "!COMPILER47ASSEMBLIESPATH!"
+
+rem If one or more directories could not be created, exit early with a non-zero error code
+if "!CREATEFAILED!"=="true" CALL :exitFailDir & EXIT /B 1
+
+rem Deploying main files, fsi.exe and fsc.exe and related
+
+echo.
+CALL :colorEcho 02 "[!ACTION!] Processing files for compiler_sdk" & echo.
+
+set SOURCEDIR=%BINDIR%
+set RESTOREDIR=!RESTOREBASE!\compiler_sdk
+CALL :checkAvailability compiler_sdk
+if "!BIN_AVAILABLE!" == "true" (
+ CALL :backupAndOrCopy fsc.exe "!COMPILERSDKPATH!"
+ CALL :backupAndOrCopy fsc.exe.config "%COMPILERSDKPATH%"
+ CALL :backupAndOrCopy FSharp.Build.dll "%COMPILERSDKPATH%"
+ CALL :backupAndOrCopy FSharp.Compiler.Private.dll "%COMPILERSDKPATH%"
+ CALL :backupAndOrCopy FSharp.Compiler.Interactive.Settings.dll "%COMPILERSDKPATH%"
+ CALL :backupAndOrCopy fsi.exe "%COMPILERSDKPATH%"
+ CALL :backupAndOrCopy fsi.exe.config "%COMPILERSDKPATH%"
+ CALL :backupAndOrCopy fsiAnyCpu.exe "%COMPILERSDKPATH%"
+ CALL :backupAndOrCopy fsiAnyCpu.exe.config "%COMPILERSDKPATH%"
+ CALL :backupAndOrCopy Microsoft.FSharp.Targets "%COMPILERSDKPATH%"
+ CALL :backupAndOrCopy Microsoft.Portable.FSharp.Targets "%COMPILERSDKPATH%"
+ CALL :backupAndOrCopy Microsoft.FSharp.NetSdk.props "%COMPILERSDKPATH%"
+ CALL :backupAndOrCopy Microsoft.FSharp.NetSdk.targets "%COMPILERSDKPATH%"
+
+ rem Special casing for SupportedRuntimes.xml, it has a different source directory, it's always there
+ set SOURCEDIR="%TOPDIR%\vsintegration\src\SupportedRuntimes"
+ CALL :backupAndOrCopy SupportedRuntimes.xml "%COMPILERSDKPATH%"
+)
+
+
+
+rem Deploying main assemblies
+
+echo.
+CALL :colorEcho 02 "[!ACTION!] Processing files for main_assemblies" & echo.
+
+set SOURCEDIR=%BINDIR%
+set RESTOREDIR=!RESTOREBASE!\main_assemblies
+CALL :checkAvailability main_assemblies
+if "!BIN_AVAILABLE!" == "true" (
+ CALL :backupAndOrCopy FSharp.Core.dll "%COMPILERMAINASSEMBLIESPATH%"
+ CALL :backupAndOrCopy FSharp.Core.optdata "%COMPILERMAINASSEMBLIESPATH%"
+ CALL :backupAndOrCopy FSharp.Core.sigdata "%COMPILERMAINASSEMBLIESPATH%"
+ CALL :backupAndOrCopy FSharp.Core.xml "%COMPILERMAINASSEMBLIESPATH%"
+)
+
+
+rem Deploying for .NET Core 3.7
+
+echo.
+CALL :colorEcho 02 "[!ACTION!] Processing files for profile_7" & echo.
+
+set SOURCEDIR=%BINDIR%\..\..\portable7\bin
+set RESTOREDIR=!RESTOREBASE!\profile_7
+CALL :checkAvailability profile_7
+if "!BIN_AVAILABLE!" == "true" (
+ CALL :backupAndOrCopy FSharp.Core.dll "%COMPILER7ASSEMBLIESPATH%"
+ CALL :backupAndOrCopy FSharp.Core.optdata "%COMPILER7ASSEMBLIESPATH%"
+ CALL :backupAndOrCopy FSharp.Core.sigdata "%COMPILER7ASSEMBLIESPATH%"
+ CALL :backupAndOrCopy FSharp.Core.xml "%COMPILER7ASSEMBLIESPATH%"
+)
+
+
+rem Deploying for .NET Core 3.78
+
+echo.
+CALL :colorEcho 02 "[!ACTION!] Processing files for profile_78" & echo.
+
+set SOURCEDIR=%BINDIR%\..\..\portable78\bin
+set RESTOREDIR=!RESTOREBASE!\profile_78
+CALL :checkAvailability profile_78
+if "!BIN_AVAILABLE!" == "true" (
+ CALL :backupAndOrCopy FSharp.Core.dll "%COMPILER78ASSEMBLIESPATH%"
+ CALL :backupAndOrCopy FSharp.Core.optdata "%COMPILER78ASSEMBLIESPATH%"
+ CALL :backupAndOrCopy FSharp.Core.sigdata "%COMPILER78ASSEMBLIESPATH%"
+ CALL :backupAndOrCopy FSharp.Core.xml "%COMPILER78ASSEMBLIESPATH%"
+)
+
+
+rem Deploying for .NET Core 3.259
+
+echo.
+CALL :colorEcho 02 "[!ACTION!] Processing files for profile_259" & echo.
+
+set SOURCEDIR=%BINDIR%\..\..\portable259\bin
+set RESTOREDIR=!RESTOREBASE!\profile_259
+CALL :checkAvailability profile_259
+if "!BIN_AVAILABLE!" == "true" (
+ CALL :backupAndOrCopy FSharp.Core.dll "%COMPILER259ASSEMBLIESPATH%"
+ CALL :backupAndOrCopy FSharp.Core.optdata "%COMPILER259ASSEMBLIESPATH%"
+ CALL :backupAndOrCopy FSharp.Core.sigdata "%COMPILER259ASSEMBLIESPATH%"
+ CALL :backupAndOrCopy FSharp.Core.xml "%COMPILER259ASSEMBLIESPATH%"
+)
+
+
+rem Deploying for .NET Portable 3.47
+
+echo.
+CALL :colorEcho 02 "[!ACTION!] Processing files for profile_47" & echo.
+
+set SOURCEDIR=%BINDIR%\..\..\portable47\bin
+set RESTOREDIR=!RESTOREBASE!\profile_47
+CALL :checkAvailability profile_47
+if "!BIN_AVAILABLE!" == "true" (
+ CALL :backupAndOrCopy FSharp.Core.dll "%COMPILER47ASSEMBLIESPATH%"
+ CALL :backupAndOrCopy FSharp.Core.optdata "%COMPILER47ASSEMBLIESPATH%"
+ CALL :backupAndOrCopy FSharp.Core.sigdata "%COMPILER47ASSEMBLIESPATH%"
+ CALL :backupAndOrCopy FSharp.Core.xml "%COMPILER47ASSEMBLIESPATH%"
+)
+
+REM TODO: this was already here (2017-09-28) and was already commented out, I think (AB) that these redirects aren't necessary anymore and can be permanently removed
REM echo ^^^^^ ^^^^^ > "%X86_PROGRAMFILES%\Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\4.%FSHARPVERSION%.0\pub.config"
-if /I "%PROCESSOR_ARCHITECTURE%"=="AMD64" (
- REG ADD "HKLM\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319\AssemblyFoldersEx\F# %FSHARPVERSION% Core Assemblies (Open Source)" /ve /t REG_SZ /f /d "%X86_PROGRAMFILES%\Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\4.%FSHARPVERSION%.0\
- REG ADD "HKLM\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.50709\AssemblyFoldersEx\F# %FSHARPVERSION% Core Assemblies (Open Source)" /ve /t REG_SZ /f /d "%X86_PROGRAMFILES%\Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\4.%FSHARPVERSION%.0\
-)
-REG ADD "HKLM\SOFTWARE\Microsoft\.NETFramework\v4.0.30319\AssemblyFoldersEx\F# %FSHARPVERSION% Core Assemblies (Open Source)" /ve /t REG_SZ /f /d "%X86_PROGRAMFILES%\Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\4.%FSHARPVERSION%.0\
-REG ADD "HKLM\SOFTWARE\Microsoft\.NETFramework\v4.0.50709\AssemblyFoldersEx\F# %FSHARPVERSION% Core Assemblies (Open Source)" /ve /t REG_SZ /f /d "%X86_PROGRAMFILES%\Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\4.%FSHARPVERSION%.0\
-
-rem Disable strong-name validation for F# binaries built from open source that are signed with the microsoft key
-%SN32% -Vr FSharp.Core,b03f5f7f11d50a3a
-%SN32% -Vr FSharp.Build,b03f5f7f11d50a3a
-%SN32% -Vr FSharp.Compiler.Interactive.Settings,b03f5f7f11d50a3a
-%SN32% -Vr HostedCompilerServer,b03f5f7f11d50a3a
-
-%SN32% -Vr FSharp.Compiler,b03f5f7f11d50a3a
-%SN32% -Vr FSharp.Compiler.Server.Shared,b03f5f7f11d50a3a
-%SN32% -Vr FSharp.Editor,b03f5f7f11d50a3a
-%SN32% -Vr FSharp.LanguageService,b03f5f7f11d50a3a
-%SN32% -Vr FSharp.LanguageService.Base,b03f5f7f11d50a3a
-%SN32% -Vr FSharp.ProjectSystem.Base,b03f5f7f11d50a3a
-%SN32% -Vr FSharp.ProjectSystem.FSharp,b03f5f7f11d50a3a
-%SN32% -Vr FSharp.ProjectSystem.PropertyPages,b03f5f7f11d50a3a
-%SN32% -Vr FSharp.VS.FSI,b03f5f7f11d50a3a
-%SN32% -Vr VisualFSharp.Unittests,b03f5f7f11d50a3a
-%SN32% -Vr VisualFSharp.Salsa,b03f5f7f11d50a3a
-
-if /i "%PROCESSOR_ARCHITECTURE%"=="AMD64" (
- %SN64% -Vr FSharp.Core,b03f5f7f11d50a3a
- %SN64% -Vr FSharp.Build,b03f5f7f11d50a3a
- %SN64% -Vr FSharp.Compiler.Interactive.Settings,b03f5f7f11d50a3a
- %SN64% -Vr HostedCompilerServer,b03f5f7f11d50a3a
-
- %SN64% -Vr FSharp.Compiler,b03f5f7f11d50a3a
- %SN64% -Vr FSharp.Compiler.Server.Shared,b03f5f7f11d50a3a
- %SN64% -Vr FSharp.Editor,b03f5f7f11d50a3a
- %SN64% -Vr FSharp.LanguageService,b03f5f7f11d50a3a
- %SN64% -Vr FSharp.LanguageService.Base,b03f5f7f11d50a3a
- %SN64% -Vr FSharp.ProjectSystem.Base,b03f5f7f11d50a3a
- %SN64% -Vr FSharp.ProjectSystem.FSharp,b03f5f7f11d50a3a
- %SN64% -Vr FSharp.ProjectSystem.PropertyPages,b03f5f7f11d50a3a
- %SN64% -Vr FSharp.VS.FSI,b03f5f7f11d50a3a
- %SN64% -Vr VisualFSharp.Unittests,b03f5f7f11d50a3a
- %SN64% -Vr VisualFSharp.Salsa,b03f5f7f11d50a3a
-)
-
-rem NGen fsc, fsi, fsiAnyCpu, and FSharp.Build.dll
-
-"%NGEN32%" install "%COMPILERSDKPATH%\fsc.exe" /queue:1
-"%NGEN32%" install "%COMPILERSDKPATH%\fsi.exe" /queue:1
-"%NGEN32%" install "%COMPILERSDKPATH%\fsiAnyCpu.exe" /queue:1
-"%NGEN32%" install "%COMPILERSDKPATH%\FSharp.Build.dll" /queue:1
-
-if /i "%PROCESSOR_ARCHITECTURE%"=="AMD64" (
- "%NGEN64%" install "%COMPILERSDKPATH%\fsiAnyCpu.exe" /queue:1
- "%NGEN64%" install "%COMPILERSDKPATH%\FSharp.Build.dll" /queue:1
+rem To add registry keys and to change strong-name validation requires Administrator access
+
+if "%DEPLOY%" == "yes" if "!ISADMIN!" == "yes" (
+ echo.
+ CALL :colorEcho 02 "[!ACTION!] Setting or adding registry keys for open source assemblies" & echo.
+ if /I "!PROCESSOR_ARCHITECTURE!"=="AMD64" (
+ REG ADD "HKLM\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319\AssemblyFoldersEx\F# !FSHARPVERSION! Core Assemblies (Open Source)" /ve /t REG_SZ /f /d "!X86_PROGRAMFILES!\Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\4.!FSHARPVERSION!.0\
+ REG ADD "HKLM\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.50709\AssemblyFoldersEx\F# !FSHARPVERSION! Core Assemblies (Open Source)" /ve /t REG_SZ /f /d "!X86_PROGRAMFILES!\Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\4.!FSHARPVERSION!.0\
+ )
+ REG ADD "HKLM\SOFTWARE\Microsoft\.NETFramework\v4.0.30319\AssemblyFoldersEx\F# !FSHARPVERSION! Core Assemblies (Open Source)" /ve /t REG_SZ /f /d "!X86_PROGRAMFILES!\Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\4.!FSHARPVERSION!.0\
+ REG ADD "HKLM\SOFTWARE\Microsoft\.NETFramework\v4.0.50709\AssemblyFoldersEx\F# !FSHARPVERSION! Core Assemblies (Open Source)" /ve /t REG_SZ /f /d "!X86_PROGRAMFILES!\Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\4.!FSHARPVERSION!.0\
+
+ rem Disable strong-name validation for F# binaries built from open source that are signed with the microsoft key
+ echo.
+ CALL :colorEcho 02 "[!ACTION!] Removing strong-name validation of F# binaries" & echo.
+ !SN32! -Vr FSharp.Core,b03f5f7f11d50a3a 1>NUL 2>NUL
+ !SN32! -Vr FSharp.Build,b03f5f7f11d50a3a 1>NUL 2>NUL
+ !SN32! -Vr FSharp.Compiler.Interactive.Settings,b03f5f7f11d50a3a 1>NUL 2>NUL
+ !SN32! -Vr HostedCompilerServer,b03f5f7f11d50a3a 1>NUL 2>NUL
+
+ !SN32! -Vr FSharp.Compiler,b03f5f7f11d50a3a 1>NUL 2>NUL
+ !SN32! -Vr FSharp.Compiler.Server.Shared,b03f5f7f11d50a3a 1>NUL 2>NUL
+ !SN32! -Vr FSharp.Editor,b03f5f7f11d50a3a 1>NUL 2>NUL
+ !SN32! -Vr FSharp.LanguageService,b03f5f7f11d50a3a 1>NUL 2>NUL
+ !SN32! -Vr FSharp.LanguageService.Base,b03f5f7f11d50a3a 1>NUL 2>NUL
+ !SN32! -Vr FSharp.ProjectSystem.Base,b03f5f7f11d50a3a 1>NUL 2>NUL
+ !SN32! -Vr FSharp.ProjectSystem.FSharp,b03f5f7f11d50a3a 1>NUL 2>NUL
+ !SN32! -Vr FSharp.ProjectSystem.PropertyPages,b03f5f7f11d50a3a 1>NUL 2>NUL
+ !SN32! -Vr FSharp.VS.FSI,b03f5f7f11d50a3a 1>NUL 2>NUL
+ !SN32! -Vr VisualFSharp.Unittests,b03f5f7f11d50a3a 1>NUL 2>NUL
+ !SN32! -Vr VisualFSharp.Salsa,b03f5f7f11d50a3a 1>NUL 2>NUL
+
+ REM Do this *in addition* to the above for x64 systems
+ if /i "!PROCESSOR_ARCHITECTURE!"=="AMD64" (
+ !SN64! -Vr FSharp.Core,b03f5f7f11d50a3a 1>NUL 2>NUL
+ !SN64! -Vr FSharp.Build,b03f5f7f11d50a3a 1>NUL 2>NUL
+ !SN64! -Vr FSharp.Compiler.Interactive.Settings,b03f5f7f11d50a3a 1>NUL 2>NUL
+ !SN64! -Vr HostedCompilerServer,b03f5f7f11d50a3a 1>NUL 2>NUL
+
+ !SN64! -Vr FSharp.Compiler,b03f5f7f11d50a3a 1>NUL 2>NUL
+ !SN64! -Vr FSharp.Compiler.Server.Shared,b03f5f7f11d50a3a 1>NUL 2>NUL
+ !SN64! -Vr FSharp.Editor,b03f5f7f11d50a3a 1>NUL 2>NUL
+ !SN64! -Vr FSharp.LanguageService,b03f5f7f11d50a3a 1>NUL 2>NUL
+ !SN64! -Vr FSharp.LanguageService.Base,b03f5f7f11d50a3a 1>NUL 2>NUL
+ !SN64! -Vr FSharp.ProjectSystem.Base,b03f5f7f11d50a3a 1>NUL 2>NUL
+ !SN64! -Vr FSharp.ProjectSystem.FSharp,b03f5f7f11d50a3a 1>NUL 2>NUL
+ !SN64! -Vr FSharp.ProjectSystem.PropertyPages,b03f5f7f11d50a3a 1>NUL 2>NUL
+ !SN64! -Vr FSharp.VS.FSI,b03f5f7f11d50a3a 1>NUL 2>NUL
+ !SN64! -Vr VisualFSharp.Unittests,b03f5f7f11d50a3a 1>NUL 2>NUL
+ !SN64! -Vr VisualFSharp.Salsa,b03f5f7f11d50a3a 1>NUL 2>NUL
+ )
+
+ rem NGen fsc, fsi, fsiAnyCpu, and FSharp.Build.dll
+
+ echo.
+ CALL :colorEcho 02 "[!ACTION!] Queuing for NGEN of FSI and FSC binaries" & echo.
+ echo [!ACTION!] NGEN of "!COMPILERSDKPATH!\fsc.exe"
+ "!NGEN32!" install "!COMPILERSDKPATH!\fsc.exe" /queue:1 1>NUL
+ echo [!ACTION!] NGEN of "!COMPILERSDKPATH!\fsi.exe"
+ "!NGEN32!" install "!COMPILERSDKPATH!\fsi.exe" /queue:1 1>NUL
+ echo [!ACTION!] NGEN of "!COMPILERSDKPATH!\fsiAnyCpu.exe"
+ "!NGEN32!" install "!COMPILERSDKPATH!\fsiAnyCpu.exe" /queue:1 1>NUL
+ echo [!ACTION!] NGEN of "!COMPILERSDKPATH!\FSharp.Build.dll"
+ "!NGEN32!" install "!COMPILERSDKPATH!\FSharp.Build.dll" /queue:1 1>NUL
+
+ if /i "!PROCESSOR_ARCHITECTURE!"=="AMD64" (
+ echo [!ACTION!] NGEN64 of "!COMPILERSDKPATH!\fsiAnyCpu.exe"
+ "!NGEN64!" install "!COMPILERSDKPATH!\fsiAnyCpu.exe" /queue:1 1>NUL
+ echo [!ACTION!] NGEN64 of "!COMPILERSDKPATH!\FSharp.Build.dll"
+ "!NGEN64!" install "!COMPILERSDKPATH!\FSharp.Build.dll" /queue:1 1>NUL
+ )
+)
+
+if "%DEPLOY%" == "yes" if "!ISADMIN!" == "no" (
+ echo.
+ CALL :colorEcho 0E "[!ACTION!] SKIPPED (no admin) Setting or adding registry keys for open source assemblies" & echo.
+ CALL :colorEcho 0E "[!ACTION!] SKIPPED (no admin) Removing strong-name validation of F# binaries" & echo.
+ CALL :colorEcho 02 "[!ACTION!] SKIPPED (no admin) Queuing for NGEN of FSI and FSC binaries" & echo.
+ SET /A WARNCOUNT+=3
+)
+
+rem Re-enable certain settings when restoring, NGEN the original files again, requires admin rights
+if "%ACTION%" == "restore" if "!ISADMIN!" == "yes" (
+
+ rem Re-enable strong-name validation for F# binaries that were previously installed
+ echo.
+ CALL :colorEcho 02 "[!ACTION!] Re-enabling strong-name validation of original F# binaries" & echo.
+ !SN32! -Vu FSharp.Core,b03f5f7f11d50a3a 2>NUL 1>NUL
+ !SN32! -Vu FSharp.Build,b03f5f7f11d50a3a 2>NUL 1>NUL
+ !SN32! -Vu FSharp.Compiler.Interactive.Settings,b03f5f7f11d50a3a 2>NUL 1>NUL
+ !SN32! -Vu HostedCompilerServer,b03f5f7f11d50a3a 2>NUL 1>NUL
+
+ !SN32! -Vu FSharp.Compiler,b03f5f7f11d50a3a 2>NUL 1>NUL
+ !SN32! -Vu FSharp.Compiler.Server.Shared,b03f5f7f11d50a3a 2>NUL 1>NUL
+ !SN32! -Vu FSharp.Editor,b03f5f7f11d50a3a 2>NUL 1>NUL
+ !SN32! -Vu FSharp.LanguageService,b03f5f7f11d50a3a 2>NUL 1>NUL
+ !SN32! -Vu FSharp.LanguageService.Base,b03f5f7f11d50a3a 2>NUL 1>NUL
+ !SN32! -Vu FSharp.ProjectSystem.Base,b03f5f7f11d50a3a 2>NUL 1>NUL
+ !SN32! -Vu FSharp.ProjectSystem.FSharp,b03f5f7f11d50a3a 2>NUL 1>NUL
+ !SN32! -Vu FSharp.ProjectSystem.PropertyPages,b03f5f7f11d50a3a 2>NUL 1>NUL
+ !SN32! -Vu FSharp.VS.FSI,b03f5f7f11d50a3a 2>NUL 1>NUL
+ !SN32! -Vu VisualFSharp.Unittests,b03f5f7f11d50a3a 2>NUL 1>NUL
+ !SN32! -Vu VisualFSharp.Salsa,b03f5f7f11d50a3a 2>NUL 1>NUL
+
+ REM Do this *in addition* to the above for x64 systems
+ if /i "!PROCESSOR_ARCHITECTURE!"=="AMD64" (
+ !SN64! -Vu FSharp.Core,b03f5f7f11d50a3a 2>NUL 1>NUL
+ !SN64! -Vu FSharp.Build,b03f5f7f11d50a3a 2>NUL 1>NUL
+ !SN64! -Vu FSharp.Compiler.Interactive.Settings,b03f5f7f11d50a3a 2>NUL 1>NUL
+ !SN64! -Vu HostedCompilerServer,b03f5f7f11d50a3a 2>NUL 1>NUL
+
+ !SN64! -Vu FSharp.Compiler,b03f5f7f11d50a3a 2>NUL 1>NUL
+ !SN64! -Vu FSharp.Compiler.Server.Shared,b03f5f7f11d50a3a 2>NUL 1>NUL
+ !SN64! -Vu FSharp.Editor,b03f5f7f11d50a3a 2>NUL 1>NUL
+ !SN64! -Vu FSharp.LanguageService,b03f5f7f11d50a3a 2>NUL 1>NUL
+ !SN64! -Vu FSharp.LanguageService.Base,b03f5f7f11d50a3a 2>NUL 1>NUL
+ !SN64! -Vu FSharp.ProjectSystem.Base,b03f5f7f11d50a3a 2>NUL 1>NUL
+ !SN64! -Vu FSharp.ProjectSystem.FSharp,b03f5f7f11d50a3a 2>NUL 1>NUL
+ !SN64! -Vu FSharp.ProjectSystem.PropertyPages,b03f5f7f11d50a3a 2>NUL 1>NUL
+ !SN64! -Vu FSharp.VS.FSI,b03f5f7f11d50a3a 2>NUL 1>NUL
+ !SN64! -Vu VisualFSharp.Unittests,b03f5f7f11d50a3a 2>NUL 1>NUL
+ !SN64! -Vu VisualFSharp.Salsa,b03f5f7f11d50a3a 2>NUL 1>NUL
+ )
+
+ rem NGen fsc, fsi, fsiAnyCpu, and FSharp.Build.dll
+
+ echo.
+ CALL :colorEcho 02 "[!ACTION!] Queuing for NGEN of FSI and FSC binaries" & echo.
+ echo [!ACTION!] NGEN of "!COMPILERSDKPATH!\fsc.exe"
+ "!NGEN32!" install "!COMPILERSDKPATH!\fsc.exe" /queue:1 1>NUL
+ echo [!ACTION!] NGEN of "!COMPILERSDKPATH!\fsi.exe"
+ "!NGEN32!" install "!COMPILERSDKPATH!\fsi.exe" /queue:1 1>NUL
+ echo [!ACTION!] NGEN of "!COMPILERSDKPATH!\fsiAnyCpu.exe"
+ "!NGEN32!" install "!COMPILERSDKPATH!\fsiAnyCpu.exe" /queue:1 1>NUL
+ echo [!ACTION!] NGEN of "!COMPILERSDKPATH!\FSharp.Build.dll"
+ "!NGEN32!" install "!COMPILERSDKPATH!\FSharp.Build.dll" /queue:1 1>NUL
+
+ if /i "!PROCESSOR_ARCHITECTURE!"=="AMD64" (
+ echo [!ACTION!] NGEN64 of "!COMPILERSDKPATH!\fsiAnyCpu.exe"
+ "!NGEN64!" install "!COMPILERSDKPATH!\fsiAnyCpu.exe" /queue:1 1>NUL
+ echo [!ACTION!] NGEN64 of "!COMPILERSDKPATH!\FSharp.Build.dll"
+ "!NGEN64!" install "!COMPILERSDKPATH!\FSharp.Build.dll" /queue:1 1>NUL
+ )
+)
+
+if "%ACTION%" == "restore" if "!ISADMIN!" == "no" (
+ CALL :colorEcho 0E "[!ACTION!] SKIPPED (no admin) Re-enabling strong-name validation of original F# binaries" & echo.
+ CALL :colorEcho 0E "[!ACTION!] SKIPPED (no admin) Queuing for NGEN of FSI and FSC binaries" & echo.
+ set /A WARNCOUNT+=2
+)
+GOTO :summary
+
+:checkAvailability
+rem Checks whether a given source is available, issues a warning otherwise, SOURCEDIR must be set to the appropriate binaries
+
+rem This will simultaneously remove the quotes of the original param and add the filename to it, then it is surrounded by quotes again
+FOR /F "usebackq tokens=*" %%I IN ('%SOURCEDIR%') DO set SOURCE="%%~fI\*"
+if not exist !SOURCE! (
+ rem For debug and release deploy it matters, but for restore and backup we don't care
+ set BIN_AVAILABLE=true
+ if "!DEPLOY!" == "yes" (
+ echo [!ACTION!] Source bindir does not exist: !SOURCE!
+ CALL :colorEcho 0E "[!ACTION!] Source binaries not found, deploy of %1 skipped" & echo. & set /A WARNCOUNT+=1
+ set BIN_AVAILABLE=false
+ )
+
+) else (
+ set BIN_AVAILABLE=true
)
+
+EXIT /B
+
+
+:backupAndOrCopy
+rem Creates a backup and copies, depending on whether debug, release, restore or backup is selected
+
+rem This will simultaneously remove the quotes of the original param and add the filename to it, then it is surrounded by quotes again
+FOR /F "usebackq tokens=*" %%I IN ('%2') DO set TARGET="%%~fI\%1"
+FOR /F "usebackq tokens=*" %%I IN ('%RESTOREDIR%') DO set BACKUP="%%~fI\%1"
+FOR /F "usebackq tokens=*" %%I IN ('%SOURCEDIR%') DO set SOURCE="%%~fI\%1"
+
+if "%ACTION%" == "backup" (
+ rem When backing up, the target becomes the source
+
+ if not exist !TARGET! (
+ rem Remove a file from the backup location if it is not part of this SDK install
+ DEL /f !BACKUP! 1>NUL 2>NUL
+ ) else (
+ rem Otherwise, copy over the original
+ CALL :copyFile !TARGET! !BACKUP!
+ )
+)
+
+if "%ACTION%" == "restore" (
+ rem When restoring, the backup location becomes the source
+
+ if not exist !BACKUP! (
+ rem If this file didn't exist in the previous installation, we should remove it to prevent confusion of left-over bits
+ DEL /f !TARGET! 1>NUL 2>NUL
+ ) else (
+ rem Otherwise, copy over the original
+ CALL :copyFile !BACKUP! !TARGET!
+ )
+)
+
+if "%DEPLOY%" == "yes" (
+ rem Deploy of debug or release build, depending on selected action
+ CALL :copyFile !SOURCE! !TARGET!
+)
+
+
+EXIT /B
+
+rem Copies a file and logs errors in red, warnings in yellow
+:copyFile
+FOR /F "usebackq tokens=*" %%I IN ('%1') DO set SOURCE="%%~fI"
+FOR /F "usebackq tokens=*" %%I IN ('%2') DO set TARGET="%%~fI"
+
+echo [%ACTION%] source: !SOURCE!
+echo [%ACTION%] target: !TARGET!
+if EXIST !SOURCE! (
+ copy /y !SOURCE! !TARGET! 1>NUL 2>copyresult.log
+ if "!errorlevel!" == "0" echo [!ACTION!] 1 file copied & set /A COPYCOUNT+=1
+ if not "!errorlevel!" == "0" (
+ set /p COPYRESULT=nul
+ set COPYRESULT=
+) else (
+ if "%ACTION%" == "backup" CALL [backup] File not found, nothing to backup
+ if "%ACTION%" == "restore" CALL :colorEcho 0E "[restore] File not found, not able to restore, possibly it didn't exist originally" & echo. & set /A WARNCOUNT+=1
+ if "%DEPLOY%" == "yes" CALL :colorEcho 0C "[!ACTION!] File not found, not able to deploy" & echo. & set /A ERRORCOUNT+=1
+)
+
+EXIT /B
+
+rem Creates a folder, if it already exists, it will do nothing, if there's an access-denied, it will set %CREATEFAILED% to true
+:tryCreateFolder
+
+rem Add a backslash safely, by taking care of auxiliary quotes
+FOR /F "usebackq tokens=*" %%I IN ('%1') DO set FOLDER_TO_BE_CREATED="%%~fI\"
+
+if not exist !FOLDER_TO_BE_CREATED! (
+ mkdir !FOLDER_TO_BE_CREATED! 2>NUL
+ if "!errorlevel!" EQU "0" (
+ echo [!ACTION!] Created directory !FOLDER_TO_BE_CREATED!
+ ) else (
+ set CREATEFAILED=true
+ echo Failed to create %1
+ CALL :colorEcho 0C "Could not create directory, check access rights or whether a file with that name exists "
+ echo.
+ echo.
+ )
+)
+
+EXIT /B
+
+:summary
+
+echo.
+if not "%ACTION%" == "restore" if not "%ACTION%" == "backup" echo Finished installing F# SDK and other bits. The following directories were updated and & echo a backup is written to %RESTOREDIR%.
+if "%ACTION%" == "restore" echo Finished restoring original F# SDK and other bits. The following directories were used while & echo restoring a backup from %RESTOREDIR%.
+if "%ACTION%" == "backup" echo Finished creating a backup in %RESTOREBASE%.
+
+echo.
+echo Root location: %TOPDIR%
+if "!ACTION!" == "debug" echo Debug bin location: %TOPDIR%\debug\net40\bin
+if "!ACTION!" == "release" echo Release bin location: %TOPDIR%\release\net40\bin
+if "!DEPLOY!" == "no" echo Backup location: %RESTOREBASE%
+echo.
+echo Target locations used:
+echo.
+echo Win SDK tools: %WINSDKNETFXTOOLS%
+echo Compiler SDK path: %COMPILERSDKPATH%
+echo F# compiler main assemblies: %COMPILERMAINASSEMBLIESPATH%
+echo Portable profile 7: %COMPILER7ASSEMBLIESPATH%
+echo Portable profile 78: %COMPILER78ASSEMBLIESPATH%
+echo Portable profile 259: %COMPILER259ASSEMBLIESPATH%
+echo Portable profile 47: %COMPILER47ASSEMBLIESPATH%
+echo.
+
+rem Display success, warning, error counts
+
+if "%ACTION%" == "backup" SET VERB=backed up
+if "%ACTION%" == "restore" SET VERB=restored
+if "%DEPLOY%" == "yes" SET VERB=deployed
+CALL :colorEcho 0A "A total of %COPYCOUNT% file(s) were %VERB%." & echo.
+
+if %ERRORCOUNT% equ 1 CALL :colorEcho 0C "%ERRORCOUNT% error reported, see log" & echo.
+if %ERRORCOUNT% gtr 1 CALL :colorEcho 0C "%ERRORCOUNT% errors reported, see log" & echo.
+if %ERRORCOUNT% equ 0 CALL :colorEcho 0A "No errors reported" & echo.
+
+if %WARNCOUNT% equ 1 CALL :colorEcho 0E "%WARNCOUNT% warning reported, see log" & echo.
+if %WARNCOUNT% gtr 1 CALL :colorEcho 0E "%WARNCOUNT% warnings reported, see log" & echo.
+if %WARNCOUNT% equ 0 CALL :colorEcho 0A "No warnings reported" & echo.
+
+rem Return non-zero error code for use-cases where this script is called from other scripts
+if %ERRORCOUNT% gtr 0 EXIT /B 1
+EXIT /B 0
+
+GOTO :EOF
+
+:exitFailDir
+
+echo.
+CALL :colorEcho 0C "One or more directories failed to be created. No files have been copied." & echo.
+echo.
+echo Possible causes include:
+echo - Insufficient rights to create directories in this folder
+echo - A file with that name already exists
+echo.
+echo No error is raised if the directory exists.
+echo No files were copied or backed up.
+echo.
+
+rem Return non-zero error code for use-cases where this script is called from other scripts
+EXIT /B 1
+
+:checkPrequisites
+rem Whether or not we have administrator rights
+
+SET ISADMIN=yes
+
+rem The error level of NET SESSION is set to 2 when you don't have administrator rights, simplest hack
+net sessions 1>NUL 2>NUL
+if %ERRORLEVEL% GTR 0 (
+ SET ISADMIN=no
+ CALL :colorEcho 0E "[!ACTION!] Started without administrator access, strong-naming will not be adjusted, reg-keys not changed" & echo.
+ SET /A WARNCOUNT+=1
+)
+
+EXIT /B
+
+
+rem See: https://stackoverflow.com/a/21666354/111575
+rem Prevent accidentally entering the colorEcho label
+GOTO :EOF
+:colorEcho
+ "%~2"
+findstr /v /a:%1 /R "^$" "%~2" nul
+del "%~2" > nul 2>&1i
\ No newline at end of file