{ pkgs }: let wfvm = import ../. { inherit pkgs; }; in { anaconda3 = { name = "Anaconda3"; script = let Anaconda3 = pkgs.fetchurl { name = "Anaconda3.exe"; url = "https://repo.anaconda.com/archive/Anaconda3-2021.05-Windows-x86_64.exe"; sha256 = "1lpk7k4gydyk524z1nk4rrninrwi20g2ias2njc9w0a40hwl5nwk"; }; in '' ln -s ${Anaconda3} ./Anaconda3.exe win-put Anaconda3.exe . echo Running Anaconda installer... win-exec 'start /wait "" .\Anaconda3.exe /S /D=%UserProfile%\Anaconda3' echo Anaconda installer finished ''; }; msys2 = { name = "MSYS2"; buildInputs = [ pkgs.expect ]; script = let msys2 = pkgs.fetchurl { name = "msys2.exe"; url = "https://github.com/msys2/msys2-installer/releases/download/2020-06-02/msys2-x86_64-20200602.exe"; sha256 = "1mswlfybvk42vdr4r85dypgkwhrp5ff47gcbxgjqwq86ym44xzd4"; }; msys2-auto-install = pkgs.fetchurl { url = "https://raw.githubusercontent.com/msys2/msys2-installer/7b4b35f65904d03399d5dfb8fc4e5729b0b4d81f/auto-install.js"; sha256 = "17fq1xprbs00j8wb4m0w1x4dvb48qb5hwa3zx77snlhw8226d81y"; }; in '' ln -s ${msys2} ./msys2.exe ln -s ${msys2-auto-install} ./auto-install.js win-put msys2.exe . win-put auto-install.js . echo Running MSYS2 installer... # work around MSYS2 installer bug that prevents it from closing at the end of unattended install expect -c 'set timeout 600; spawn win-exec ".\\msys2.exe --script auto-install.js -v InstallPrefix=C:\\msys64"; expect FinishedPageCallback { close }' echo MSYS2 installer finished ''; }; msys2-packages = msys-packages: { name = "MSYS2-packages"; script = let msys-packages-put = pkgs.lib.strings.concatStringsSep "\n" (map (package: ''win-put ${package} 'msyspackages' '') msys-packages); in # Windows command line is so shitty it can't even do glob expansion. Why do people use Windows? '' win-exec 'mkdir msyspackages' ${msys-packages-put} cat > installmsyspackages.bat << EOF set MSYS=c:\msys64 set ARCH=64 set PATH=%MSYS%\usr\bin;%MSYS%\mingw%ARCH%\bin;%PATH% bash -c "pacman -U --noconfirm C:/Users/wfvm/msyspackages/*" EOF win-put installmsyspackages.bat . win-exec installmsyspackages ''; }; msvc = { # Those instructions are vaguely correct: # https://docs.microsoft.com/en-us/visualstudio/install/create-an-offline-installation-of-visual-studio?view=vs-2019 name = "MSVC"; script = let bootstrapper = pkgs.fetchurl { name = "RESTRICTDIST-vs_Community.exe"; url = "https://download.visualstudio.microsoft.com/download/pr/ac05c4f5-0da1-429f-8701-ce509ac69926/cc9556137c66a373670376d6db2fc5c5c937b2b0bf7b3d3cac11c69e33615511/vs_Community.exe"; sha256 = "04amc4rrxihimhy3syxzn2r3gjf5qlpxpmkn0dkp78v6gh9md5fc"; }; # This touchy-feely "community" piece of trash seems deliberately crafted to break Wine, so we use the VM to run it. download-vs = wfvm.utils.wfvm-run { name = "download-vs"; image = wfvm.makeWindowsImage { }; isolateNetwork = false; script = '' ln -s ${bootstrapper} vs_Community.exe ${wfvm.utils.win-put}/bin/win-put vs_Community.exe rm vs_Community.exe ${wfvm.utils.win-exec}/bin/win-exec "vs_Community.exe --quiet --norestart --layout c:\vslayout --add Microsoft.VisualStudio.Workload.NativeDesktop --includeRecommended --lang en-US" ${wfvm.utils.win-get}/bin/win-get /c:/vslayout ''; }; cache = pkgs.stdenv.mkDerivation { name = "RESTRICTDIST-vs"; outputHashAlgo = "sha256"; outputHashMode = "recursive"; outputHash = "0fp7a6prjp8n8sirwday13wis3xyzhmrwi377y3x89nxzysp0mnv"; phases = [ "buildPhase" ]; buildInputs = [ download-vs ]; buildPhase = '' mkdir $out cd $out wfvm-run-download-vs ''; }; in '' ln -s ${cache}/vslayout vslayout win-put vslayout /c:/ echo "Running Visual Studio installer" win-exec "cd \vslayout && start /wait vs_Community.exe --passive --wait && echo %errorlevel%" ''; }; # You need to run the IDE at least once or else most of the Visual Studio trashware won't actually work. # With the /ResetSettings flag, it will actually start without pestering you about opening a Microsoft account. msvc-ide-unbreak = { name = "MSVC-ide-unbreak"; script = '' win-exec 'cd "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE" && devenv /ResetSettings' sleep 40 ''; }; # Disable the Windows firewall disable-firewall = { name = "disable-firewall"; script = '' echo Disabling firewall win-exec "netsh advfirewall set allprofiles state off" ''; }; # Disable automatic power management which causes the machine to go # into standby after periods without mouse wiggling. disable-autosleep = { name = "disable-autosleep"; script = '' echo Disabling autosleep win-exec "powercfg /x -hibernate-timeout-ac 0" win-exec "powercfg /x -hibernate-timeout-dc 0" win-exec "powercfg /x -disk-timeout-ac 0" win-exec "powercfg /x -disk-timeout-dc 0" win-exec "powercfg /x -monitor-timeout-ac 0" win-exec "powercfg /x -monitor-timeout-dc 0" win-exec "powercfg /x -standby-timeout-ac 0" win-exec "powercfg /x -standby-timeout-dc 0" ''; }; # Turn off automatic locking of idle user sessions disable-autolock = { name = "disable-autolock"; script = '' echo Disabling autolock win-exec "reg add HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Personalization /v NoLockScreen /t REG_DWORD /d 1" ''; }; # Chain together layers that are quick to run so that the VM does # not have to be started/shutdown for each. collapseLayers = scripts: { name = pkgs.lib.concatMapStringsSep "-" ({ name, ... }: name) scripts; script = builtins.concatStringsSep "\n" ( map ({ script, ... }: script) scripts ); buildInputs = builtins.concatMap ({ buildInputs ? [], ... }: buildInputs) scripts; }; }