├── .editorconfig ├── .github └── workflows │ └── build.yml ├── .gitignore ├── LICENSE ├── README.md ├── RefreshEnv.cmd ├── build-openocd.sh ├── build.ps1 ├── common.ps1 ├── docs └── ReadMe.txt ├── git.inf ├── pico-docs.ps1 ├── pico-env.cmd ├── pico-setup.cmd ├── tests ├── common.Tests.ps1 ├── setup-oldvs.ps1 └── setup.ps1 ├── tools.json ├── update.ps1 ├── version.txt ├── vssetup.ps1 ├── x64.json └── x86.json /.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | end_of_line = crlf 7 | indent_style = space 8 | indent_size = 2 9 | insert_final_newline = true 10 | trim_trailing_whitespace = true 11 | 12 | [*.md] 13 | max_line_length = off 14 | trim_trailing_whitespace = false 15 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | on: [push, pull_request] 3 | jobs: 4 | 5 | Test-Scripts: 6 | runs-on: windows-latest 7 | steps: 8 | 9 | - name: Checkout 10 | uses: actions/checkout@v2 11 | 12 | - name: Test scripts 13 | shell: pwsh 14 | run: | 15 | $pesterConfig = @{ 16 | Run = @{ 17 | Path = ".\tests\common.Tests.ps1" 18 | Exit = $true 19 | } 20 | TestResult = @{ 21 | Enabled = $true 22 | OutputPath = "testResults.xml" 23 | OutputFormat = "NUnitXML" 24 | } 25 | Output = @{ 26 | Verbosity = "Detailed" 27 | } 28 | } 29 | Invoke-Pester -Configuration $pesterConfig 30 | 31 | - name: Upload test results 32 | uses: actions/upload-artifact@v2 33 | if: ${{ always() }} 34 | with: 35 | name: Pester-Test-Results 36 | path: testResults.xml 37 | 38 | Build: 39 | runs-on: windows-latest 40 | needs: Test-Scripts 41 | strategy: 42 | matrix: 43 | bitness: ['x86', 'x64'] 44 | steps: 45 | 46 | - name: Checkout 47 | uses: actions/checkout@v2 48 | 49 | - name: Build ${{ matrix.bitness }} 50 | shell: pwsh 51 | run: | 52 | Set-StrictMode -Version Latest 53 | $ErrorActionPreference = 'Stop' 54 | $ProgressPreference = 'SilentlyContinue' 55 | 56 | .\build.ps1 .\${{ matrix.bitness }}.json -MSYS2Path C:\msys64 57 | 58 | - name: Upload build artifacts 59 | uses: actions/upload-artifact@v2 60 | with: 61 | name: Package-${{ matrix.bitness }} 62 | path: bin/ 63 | 64 | Test-Installer: 65 | runs-on: windows-${{ matrix.winver }} 66 | needs: Build 67 | strategy: 68 | fail-fast: false 69 | matrix: 70 | bitness: ['x86', 'x64'] 71 | winver: ['2019', '2022'] 72 | steps: 73 | 74 | - name: Checkout 75 | uses: actions/checkout@v2 76 | 77 | - name: Download installer artifact 78 | uses: actions/download-artifact@v2 79 | with: 80 | name: Package-${{ matrix.bitness }} 81 | path: bin 82 | 83 | - name: Test installer 84 | shell: pwsh 85 | run: docker run --rm -v "$(Get-Location):C:\repo" mcr.microsoft.com/windows/servercore:ltsc${{ matrix.winver }} 86 | powershell -NoProfile -NonInteractive -ExecutionPolicy Bypass -Command "cd C:\repo; .\tests\setup.ps1" 87 | 88 | - name: Upload installer logs 89 | uses: actions/upload-artifact@v2 90 | if: ${{ always() }} 91 | with: 92 | name: Installer-Logs-Windows-${{ matrix.winver }}-${{ matrix.bitness }} 93 | path: logs/ 94 | 95 | Test-Installer-ExistingVS: 96 | runs-on: windows-2019 97 | needs: Build 98 | steps: 99 | 100 | - name: Checkout 101 | uses: actions/checkout@v2 102 | 103 | - name: Download installer artifact 104 | uses: actions/download-artifact@v2 105 | with: 106 | name: Package-x64 107 | path: bin 108 | 109 | - name: Test installer 110 | shell: pwsh 111 | run: docker run --rm -v "$(Get-Location):C:\repo" mcr.microsoft.com/windows/servercore:ltsc2019 112 | powershell -NoProfile -NonInteractive -ExecutionPolicy Bypass -Command "cd C:\repo; .\tests\setup-oldvs.ps1; .\tests\setup.ps1" 113 | 114 | - name: Upload installer logs 115 | uses: actions/upload-artifact@v2 116 | if: ${{ always() }} 117 | with: 118 | name: Installer-Logs-Windows-2019-x64-ExistingVS 119 | path: logs/ 120 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Downloaded installers 2 | installers/ 3 | 4 | # Generated NSIS scripts 5 | *.nsi 6 | 7 | # Built installers 8 | bin/ 9 | 10 | # Build tools 11 | build/ 12 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Pico setup for Windows 2 | 3 | This project has now moved to Raspberry Pi! Development will now continue at [raspberrypi/pico-setup-windows](https://github.com/raspberrypi/pico-setup-windows). Please submit all issues and pull requests there. 4 | 5 | [Download the latest release](https://github.com/raspberrypi/pico-setup-windows/releases/latest/download/pico-setup-windows-x64-standalone.exe) 6 | 7 | The previous sources [are still around](https://github.com/ndabas/pico-setup-windows/tree/master). 8 | -------------------------------------------------------------------------------- /RefreshEnv.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | :: 3 | :: RefreshEnv.cmd 4 | :: 5 | :: Batch file to read environment variables from registry and 6 | :: set session variables to these values. 7 | :: 8 | :: With this batch file, there should be no need to reload command 9 | :: environment every time you want environment changes to propagate 10 | 11 | ::echo "RefreshEnv.cmd only works from cmd.exe, please install the Chocolatey Profile to take advantage of refreshenv from PowerShell" 12 | echo | set /p dummy="Refreshing environment variables from registry for cmd.exe. Please wait..." 13 | 14 | goto main 15 | 16 | :: Set one environment variable from registry key 17 | :SetFromReg 18 | "%WinDir%\System32\Reg" QUERY "%~1" /v "%~2" > "%TEMP%\_envset.tmp" 2>NUL 19 | for /f "usebackq skip=2 tokens=2,*" %%A IN ("%TEMP%\_envset.tmp") do ( 20 | echo/set "%~3=%%B" 21 | ) 22 | goto :EOF 23 | 24 | :: Get a list of environment variables from registry 25 | :GetRegEnv 26 | "%WinDir%\System32\Reg" QUERY "%~1" > "%TEMP%\_envget.tmp" 27 | for /f "usebackq skip=2" %%A IN ("%TEMP%\_envget.tmp") do ( 28 | if /I not "%%~A"=="Path" ( 29 | call :SetFromReg "%~1" "%%~A" "%%~A" 30 | ) 31 | ) 32 | goto :EOF 33 | 34 | :main 35 | echo/@echo off >"%TEMP%\_env.cmd" 36 | 37 | :: Slowly generating final file 38 | call :GetRegEnv "HKLM\System\CurrentControlSet\Control\Session Manager\Environment" >> "%TEMP%\_env.cmd" 39 | call :GetRegEnv "HKCU\Environment">>"%TEMP%\_env.cmd" >> "%TEMP%\_env.cmd" 40 | 41 | :: Special handling for PATH - mix both User and System 42 | call :SetFromReg "HKLM\System\CurrentControlSet\Control\Session Manager\Environment" Path Path_HKLM >> "%TEMP%\_env.cmd" 43 | call :SetFromReg "HKCU\Environment" Path Path_HKCU >> "%TEMP%\_env.cmd" 44 | 45 | :: Caution: do not insert space-chars before >> redirection sign 46 | echo/set "Path=%%Path_HKLM%%;%%Path_HKCU%%" >> "%TEMP%\_env.cmd" 47 | 48 | :: Cleanup 49 | del /f /q "%TEMP%\_envset.tmp" 2>nul 50 | del /f /q "%TEMP%\_envget.tmp" 2>nul 51 | 52 | :: capture user / architecture 53 | SET "OriginalUserName=%USERNAME%" 54 | SET "OriginalArchitecture=%PROCESSOR_ARCHITECTURE%" 55 | 56 | :: Set these variables 57 | call "%TEMP%\_env.cmd" 58 | 59 | :: Cleanup 60 | del /f /q "%TEMP%\_env.cmd" 2>nul 61 | 62 | :: reset user / architecture 63 | SET "USERNAME=%OriginalUserName%" 64 | SET "PROCESSOR_ARCHITECTURE=%OriginalArchitecture%" 65 | 66 | echo | set /p dummy="Finished." 67 | echo . 68 | -------------------------------------------------------------------------------- /build-openocd.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euo pipefail 4 | 5 | BITNESS=$1 6 | ARCH=$2 7 | OPENOCD_BRANCH="master" 8 | 9 | if [ ! -d openocd ]; then 10 | git clone "https://github.com/openocd-org/openocd.git" -b $OPENOCD_BRANCH --depth=1 11 | else 12 | git -C openocd checkout -B $OPENOCD_BRANCH 13 | git -C openocd pull --ff-only 14 | fi 15 | 16 | cd openocd 17 | ./bootstrap 18 | ./configure 19 | make clean 20 | make -j4 21 | DESTDIR="$PWD/../openocd-install" make install 22 | cp "/mingw$BITNESS/bin/libhidapi-0.dll" "$PWD/../openocd-install/mingw$BITNESS/bin" 23 | cp "/mingw$BITNESS/bin/libusb-1.0.dll" "$PWD/../openocd-install/mingw$BITNESS/bin" 24 | -------------------------------------------------------------------------------- /build.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | param ( 3 | [Parameter(Mandatory = $true, 4 | Position = 0, 5 | HelpMessage = "Path to a JSON installer configuration file.")] 6 | [Alias("PSPath")] 7 | [ValidateNotNullOrEmpty()] 8 | [string] 9 | $ConfigFile, 10 | 11 | [Parameter(HelpMessage = "Path to MSYS2 installation. MSYS2 will be downloaded and installed to this path if it doesn't exist.")] 12 | [ValidatePattern('[\\\/]msys64$')] 13 | [string] 14 | $MSYS2Path = '.\build\msys64', 15 | 16 | [switch] 17 | $SkipDownload 18 | ) 19 | 20 | Set-StrictMode -Version Latest 21 | $ErrorActionPreference = 'Stop' 22 | $ProgressPreference = 'SilentlyContinue' 23 | 24 | . "$PSScriptRoot\common.ps1" 25 | 26 | Write-Host "Building from $ConfigFile" 27 | 28 | $basename = "pico-setup-windows" 29 | $version = (Get-Content "$PSScriptRoot\version.txt").Trim() 30 | $suffix = [io.path]::GetFileNameWithoutExtension($ConfigFile) 31 | $outfile = "bin\$basename-$version-$suffix.exe" 32 | 33 | $tools = (Get-Content '.\tools.json' | ConvertFrom-Json).tools 34 | $config = Get-Content $ConfigFile | ConvertFrom-Json 35 | $bitness = $config.bitness 36 | $mingw_arch = $config.mingw_arch 37 | $installers = $config.installers 38 | 39 | ($installers + $tools) | ForEach-Object { 40 | $_ | Add-Member -NotePropertyName 'shortName' -NotePropertyValue ($_.name -replace '[^a-zA-Z0-9]', '') 41 | 42 | if ($SkipDownload) { 43 | Write-Host "Checking $($_.name): " -NoNewline 44 | if (-not (Test-Path "installers/$($_.file)")) { 45 | Write-Error "installers/$($_.file) not found" 46 | } 47 | } 48 | else { 49 | Write-Host "Downloading $($_.name): " -NoNewline 50 | exec { curl.exe --fail --silent --show-error --url "$($_.href)" --location --output "installers/$($_.file)" --create-dirs --remote-time --time-cond "installers/$($_.file)" } 51 | } 52 | 53 | # Display versions of packaged installers, for information only. We try to 54 | # extract it from: 55 | # 1. The file name 56 | # 2. The download URL 57 | # 3. The version metadata in the file 58 | # 59 | # This fails for MSYS2, because there is no version number (only a timestamp) 60 | # and the version that gets reported is 7-zip SFX version. 61 | $version = '' 62 | $versionRegEx = '([0-9]+\.)+[0-9]+' 63 | if ($_.file -match $versionRegEx -or $_.href -match $versionRegEx) { 64 | $version = $Matches[0] 65 | } else { 66 | $version = (Get-ChildItem ".\installers\$($_.file)").VersionInfo.ProductVersion 67 | } 68 | 69 | if ($version) { 70 | Write-Host $version 71 | } else { 72 | Write-Host $_.file 73 | } 74 | } 75 | 76 | mkdirp "build" 77 | mkdirp "bin" 78 | 79 | if (-not (Test-Path $MSYS2Path)) { 80 | Write-Host 'Extracting MSYS2' 81 | exec { & .\installers\msys2.exe -y "-o$(Resolve-Path (Split-Path $MSYS2Path -Parent))" } 82 | } 83 | 84 | if (-not (Test-Path build\NSIS)) { 85 | Write-Host 'Extracting NSIS' 86 | Expand-Archive '.\installers\nsis.zip' -DestinationPath '.\build' 87 | Rename-Item (Resolve-Path '.\build\nsis-*').Path 'NSIS' 88 | Expand-Archive '.\installers\nsis-log.zip' -DestinationPath '.\build\NSIS' -Force 89 | } 90 | 91 | function msys { 92 | param ([string] $cmd) 93 | 94 | exec { & "$MSYS2Path\usr\bin\bash" -leo pipefail -c "$cmd" } 95 | } 96 | 97 | # Preserve the current working directory 98 | $env:CHERE_INVOKING = 'yes' 99 | # Start MINGW32/64 environment 100 | $env:MSYSTEM = "MINGW$bitness" 101 | 102 | if (-not (Test-Path ".\build\openocd-install\mingw$bitness")) { 103 | # First run setup 104 | msys 'uname -a' 105 | # Core update 106 | msys 'pacman --noconfirm -Syuu' 107 | # Normal update 108 | msys 'pacman --noconfirm -Suu' 109 | 110 | msys "pacman -S --noconfirm --needed autoconf automake git libtool make mingw-w64-${mingw_arch}-toolchain mingw-w64-${mingw_arch}-libusb mingw-w64-${mingw_arch}-hidapi p7zip pkg-config wget" 111 | 112 | # Keep it clean 113 | if (Test-Path .\build\openocd) { 114 | Remove-Item .\build\openocd -Recurse -Force 115 | } 116 | 117 | msys "cd build && ../build-openocd.sh $bitness $mingw_arch" 118 | } 119 | 120 | @" 121 | !include "MUI2.nsh" 122 | !include "WordFunc.nsh" 123 | 124 | !define TITLE "Pico setup for Windows" 125 | 126 | Name "`${TITLE}" 127 | Caption "`${TITLE}" 128 | 129 | VIAddVersionKey "FileDescription" "`${TITLE}" 130 | VIAddVersionKey "InternalName" "$basename" 131 | VIAddVersionKey "ProductName" "`${TITLE}" 132 | VIAddVersionKey "FileVersion" "$version" 133 | VIAddVersionKey "LegalCopyright" "" 134 | VIFileVersion $version.0 135 | VIProductVersion $version.0 136 | 137 | OutFile "$outfile" 138 | Unicode True 139 | 140 | ; Since we're packaging up a bunch of installers, the "Space required" shown is inaccurate 141 | SpaceTexts "none" 142 | 143 | InstallDir "`$DOCUMENTS\Pico" 144 | 145 | ;Get installation folder from registry if available 146 | InstallDirRegKey HKCU "Software\$basename" "" 147 | 148 | !define MUI_ABORTWARNING 149 | 150 | !define MUI_WELCOMEPAGE_TITLE "`${TITLE}" 151 | 152 | !define MUI_COMPONENTSPAGE_SMALLDESC 153 | 154 | !define MUI_FINISHPAGE_RUN_TEXT "Clone and build Pico repos" 155 | !define MUI_FINISHPAGE_RUN 156 | !define MUI_FINISHPAGE_RUN_FUNCTION RunBuild 157 | 158 | !define MUI_FINISHPAGE_SHOWREADME "`$INSTDIR\ReadMe.txt" 159 | !define MUI_FINISHPAGE_SHOWREADME_TEXT "Show ReadMe" 160 | 161 | !define MUI_FINISHPAGE_NOAUTOCLOSE 162 | 163 | !insertmacro MUI_PAGE_WELCOME 164 | ;!insertmacro MUI_PAGE_LICENSE "`${NSISDIR}\Docs\Modern UI\License.txt" 165 | !insertmacro MUI_PAGE_COMPONENTS 166 | !insertmacro MUI_PAGE_DIRECTORY 167 | !insertmacro MUI_PAGE_INSTFILES 168 | !insertmacro MUI_PAGE_FINISH 169 | 170 | !insertmacro MUI_LANGUAGE "English" 171 | 172 | Section 173 | 174 | ; Make sure that `$INSTDIR exists before enabling logging 175 | SetOutPath `$INSTDIR 176 | LogSet on 177 | 178 | ReadRegStr `$R0 HKLM "SOFTWARE\Microsoft\PowerShell\3\PowerShellEngine" "PowerShellVersion" 179 | DetailPrint "Detected PowerShell version: `$R0" 180 | `${VersionCompare} "5.1.0.0" `$R0 `$R1 181 | `${If} `$R1 < 2 182 | Abort "Windows PowerShell 5.1 is required for this installation. Please install WMF 5.1 and re-run setup." 183 | `${EndIf} 184 | ClearErrors 185 | 186 | ; https://docs.microsoft.com/en-us/dotnet/framework/migration-guide/how-to-determine-which-versions-are-installed 187 | ; Check for .NET Framework 4.6.2, required for Visual Studio 2019 Build Tools 188 | ReadRegDWORD `$R0 HKLM "SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full" "Release" 189 | DetailPrint "Detected .NET Framework 4 release: `$R0" 190 | `${If} `$R0 < 394802 191 | Abort ".NET Framework 4.6.2 or later is required for this installation. Please install the latest .NET Framework 4.x and re-run setup." 192 | `${EndIf} 193 | ClearErrors 194 | 195 | InitPluginsDir 196 | File /oname=`$TEMP\RefreshEnv.cmd RefreshEnv.cmd 197 | 198 | SectionEnd 199 | 200 | $($installers | ForEach-Object { 201 | @" 202 | 203 | Section "$($_.name)" Sec$($_.shortName) 204 | 205 | ClearErrors 206 | 207 | $(if ($_ | Get-Member additionalFiles) { 208 | $_.additionalFiles | ForEach-Object { 209 | "File /oname=`$PLUGINSDIR\$(Split-Path -Leaf $_) $_`r`n" 210 | } 211 | }) 212 | 213 | SetOutPath "`$TEMP" 214 | File "installers\$($_.file)" 215 | StrCpy `$0 "`$TEMP\$($_.file)" 216 | ExecWait '$($_.exec)' `$1 217 | DetailPrint "$($_.name) returned `$1" 218 | Delete /REBOOTOK "`$0" 219 | 220 | `${If} `${Errors} 221 | Abort "Installation of $($_.name) failed" 222 | $(if ($_ | Get-Member rebootExitCodes) { 223 | $_.rebootExitCodes | ForEach-Object { 224 | "`${ElseIf} `$1 = $_`r`n SetRebootFlag true" 225 | } 226 | }) 227 | `${ElseIf} `$1 <> 0 228 | Abort "Installation of $($_.name) failed" 229 | `${EndIf} 230 | 231 | SectionEnd 232 | 233 | LangString DESC_Sec$($_.shortName) `${LANG_ENGLISH} "$($_.name)" 234 | 235 | "@ 236 | }) 237 | 238 | Section "VS Code Extensions" SecCodeExts 239 | 240 | ReadEnvStr `$0 COMSPEC 241 | nsExec::ExecToLog '"`$0" /c call "`$TEMP\RefreshEnv.cmd" && code --install-extension marus25.cortex-debug' 242 | Pop `$1 243 | nsExec::ExecToLog '"`$0" /c call "`$TEMP\RefreshEnv.cmd" && code --install-extension ms-vscode.cmake-tools' 244 | Pop `$1 245 | nsExec::ExecToLog '"`$0" /c call "`$TEMP\RefreshEnv.cmd" && code --install-extension ms-vscode.cpptools' 246 | Pop `$1 247 | 248 | SectionEnd 249 | 250 | LangString DESC_SecCodeExts `${LANG_ENGLISH} "Recommended extensions for Visual Studio Code: C/C++, CMake-Tools, and Cortex-Debug" 251 | 252 | Section "OpenOCD" SecOpenOCD 253 | 254 | SetOutPath "`$INSTDIR\tools\openocd" 255 | File "build\openocd-install\mingw$bitness\bin\*.*" 256 | SetOutPath "`$INSTDIR\tools\openocd\scripts" 257 | File /r "build\openocd-install\mingw$bitness\share\openocd\scripts\*.*" 258 | 259 | SectionEnd 260 | 261 | LangString DESC_SecOpenOCD `${LANG_ENGLISH} "Open On-Chip Debugger with picoprobe support" 262 | 263 | Section "Pico environment" SecPico 264 | 265 | SetOutPath "`$INSTDIR" 266 | File "pico-env.cmd" 267 | File "pico-setup.cmd" 268 | File "docs\ReadMe.txt" 269 | 270 | CreateShortcut "`$INSTDIR\Developer Command Prompt for Pico.lnk" "cmd.exe" '/k "`$INSTDIR\pico-env.cmd"' 271 | 272 | ; Unconditionally create a shortcut for VS Code -- in case the user had it 273 | ; installed already, or if they install it later 274 | CreateShortcut "`$INSTDIR\Visual Studio Code for Pico.lnk" "cmd.exe" '/c (call "`$INSTDIR\pico-env.cmd" && code) || pause' 275 | 276 | ; SetOutPath is needed here to set the working directory for the shortcut 277 | SetOutPath "`$INSTDIR\pico-project-generator" 278 | CreateShortcut "`$INSTDIR\Pico Project Generator.lnk" "cmd.exe" '/c (call "`$INSTDIR\pico-env.cmd" && python "`$INSTDIR\pico-project-generator\pico_project.py" --gui) || pause' 279 | 280 | ; Reset working dir for pico-setup.cmd launched from the finish page 281 | SetOutPath "`$INSTDIR" 282 | 283 | SectionEnd 284 | 285 | LangString DESC_SecPico `${LANG_ENGLISH} "Scripts for cloning the Pico SDK and tools repos, and for setting up your Pico development environment." 286 | 287 | Section "Download documents and files" SecDocs 288 | 289 | SetOutPath "`$INSTDIR" 290 | File "common.ps1" 291 | File "pico-docs.ps1" 292 | 293 | SectionEnd 294 | 295 | Function RunBuild 296 | 297 | ReadEnvStr `$0 COMSPEC 298 | Exec '"`$0" /k call "`$TEMP\RefreshEnv.cmd" && del "`$TEMP\RefreshEnv.cmd" && call "`$INSTDIR\pico-setup.cmd" 1' 299 | 300 | FunctionEnd 301 | 302 | LangString DESC_SecDocs `${LANG_ENGLISH} "Adds a script to download the latest Pico documents, design files, and UF2 files." 303 | 304 | !insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN 305 | !insertmacro MUI_DESCRIPTION_TEXT `${SecCodeExts} `$(DESC_SecCodeExts) 306 | !insertmacro MUI_DESCRIPTION_TEXT `${SecOpenOCD} `$(DESC_SecOpenOCD) 307 | !insertmacro MUI_DESCRIPTION_TEXT `${SecPico} `$(DESC_SecPico) 308 | !insertmacro MUI_DESCRIPTION_TEXT `${SecDocs} `$(DESC_SecDocs) 309 | $($installers | ForEach-Object { 310 | " !insertmacro MUI_DESCRIPTION_TEXT `${Sec$($_.shortName)} `$(DESC_Sec$($_.shortName))`n" 311 | }) 312 | !insertmacro MUI_FUNCTION_DESCRIPTION_END 313 | "@ | Set-Content ".\$basename-$suffix.nsi" 314 | 315 | exec { .\build\NSIS\makensis ".\$basename-$suffix.nsi" } 316 | Write-Host "Installer saved to $outfile" 317 | 318 | # Package OpenOCD separately as well 319 | 320 | $version = (cmd /c ".\build\openocd-install\mingw$bitness\bin\openocd.exe" --version '2>&1')[0] 321 | if (-not ($version -match 'Open On-Chip Debugger (?[a-zA-Z0-9\.\-+]+) \((?[0-9\-:]+)\)')) { 322 | Write-Error 'Could not determine openocd version' 323 | } 324 | 325 | $filename = 'openocd-{0}-{1}-{2}.zip' -f 326 | ($Matches.version -replace '-dirty$', ''), 327 | ($Matches.timestamp -replace '[:-]', ''), 328 | $suffix 329 | 330 | Write-Host "Saving OpenOCD package to $filename" 331 | tar -a -cf "bin\$filename" -C "build\openocd-install\mingw$bitness\bin" * -C "..\share\openocd" "scripts" 332 | -------------------------------------------------------------------------------- /common.ps1: -------------------------------------------------------------------------------- 1 | function crawl { 2 | param ([string]$url) 3 | 4 | (Invoke-WebRequest $url -UseBasicParsing).Links | 5 | Where-Object { 6 | ($_ | Get-Member href) -and 7 | [uri]::IsWellFormedUriString($_.href, [System.UriKind]::RelativeOrAbsolute) 8 | } | 9 | ForEach-Object { 10 | $href = [System.Net.WebUtility]::HtmlDecode($_.href) 11 | 12 | try { 13 | (New-Object System.Uri([uri]$url, $href)).AbsoluteUri 14 | } 15 | catch { 16 | $href 17 | } 18 | } 19 | } 20 | 21 | function mkdirp { 22 | param ([string] $dir) 23 | 24 | New-Item -Path $dir -Type Directory -Force | Out-Null 25 | } 26 | 27 | function exec { 28 | param ([scriptblock]$private:cmd) 29 | 30 | $private:eap = $ErrorActionPreference 31 | $ErrorActionPreference = 'Continue' 32 | $global:LASTEXITCODE = 0 33 | 34 | try { 35 | # Convert stderr in ErrorRecord objects back to strings 36 | & $cmd 2>&1 | ForEach-Object { "$_" } 37 | 38 | if ($LASTEXITCODE -ne 0) { 39 | throw "Command '$cmd' exited with code $LASTEXITCODE" 40 | } 41 | } 42 | finally { 43 | $ErrorActionPreference = $eap 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /docs/ReadMe.txt: -------------------------------------------------------------------------------- 1 | Pico setup for Windows 2 | 3 | Download the latest release from 4 | https://github.com/ndabas/pico-setup-windows/releases 5 | 6 | Developer Command Prompt for Pico 7 | Use this shortcut to launch a command prompt configured with the tools and 8 | environment variables needed for Pico development. Note that you should launch 9 | your editor or IDE from this prompt so that it inherits the needed environment 10 | as well. 11 | 12 | Visual Studio Code for Pico 13 | Start Visual Studio Code using this link to have the correct environment 14 | variables (like PATH and PICO_SDK_PATH) set for development. 15 | 16 | pico-env.cmd 17 | Use this batch file to set up a command prompt with the required environment 18 | variables for Pico development. 19 | 20 | pico-setup.cmd 21 | This batch file clones the Pico SDK and related Git repositories, and runs a 22 | few test builds to ensure that everything is working as expected. 23 | 24 | design, docs, uf2 25 | These folders contain the Getting Started documents, datasheets, design files, 26 | and UF2 files from the Raspberry Pi Pico getting-started page. 27 | 28 | pico-docs.ps1 29 | This PowerShell script downloads all of the latest documents and files from the 30 | Raspberry Pi Pico website. 31 | 32 | Pico Project Generator 33 | This is a Python application to help you create new Pico projects. 34 | 35 | tools\openocd\openocd.exe 36 | OpenOCD with picoprobe support. Launch from the Developer Command Prompt for 37 | Pico using a command like this: 38 | openocd -f interface/cmsis-dap.cfg -f target/rp2040.cfg 39 | 40 | You can get the latest Picoprobe binaries from https://github.com/raspberrypi/picoprobe/releases. 41 | 42 | Uninstall 43 | Just delete this directory. Any other software that you installed using Pico 44 | setup for Windows will have its own uninstaller. 45 | -------------------------------------------------------------------------------- /git.inf: -------------------------------------------------------------------------------- 1 | [Setup] 2 | PathOption=Cmd 3 | CRLFOption=CRLFCommitAsIs 4 | BashTerminalOption=ConHost 5 | EnablePseudoConsoleSupport=Enabled 6 | -------------------------------------------------------------------------------- /pico-docs.ps1: -------------------------------------------------------------------------------- 1 | Set-StrictMode -Version Latest 2 | $ErrorActionPreference = 'Stop' 3 | $ProgressPreference = 'SilentlyContinue' 4 | 5 | . "$PSScriptRoot\common.ps1" 6 | 7 | [Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12 8 | 9 | crawl 'https://www.raspberrypi.com/documentation/microcontrollers/raspberry-pi-pico.html' | 10 | Sort-Object -Unique | 11 | Where-Object { ([uri]$_).Authority -match '\.raspberrypi.com$' } | 12 | ForEach-Object { 13 | $dir = $null 14 | 15 | switch -regex ($_) { 16 | '\.pdf$' { $dir = 'docs' } 17 | '\.zip$' { $dir = 'design' } 18 | '\.uf2$' { $dir = 'uf2' } 19 | } 20 | 21 | if ($dir) { 22 | Write-Host "Downloading $_" 23 | mkdirp $dir 24 | $fileName = ([uri]$_).Segments[-1] 25 | Invoke-WebRequest $_ -OutFile (Join-Path $dir $fileName) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /pico-env.cmd: -------------------------------------------------------------------------------- 1 | @if not defined _echo echo off 2 | 3 | set errors=0 4 | goto main 5 | 6 | :AddToPath 7 | 8 | if exist "%~1" ( 9 | set "PATH=%~1;%PATH%" 10 | ) 11 | 12 | goto :EOF 13 | 14 | :VerifyExe 15 | 16 | echo Checking %1... 17 | cmd /c %2 >NUL 2>NUL 18 | if %ERRORLEVEL% neq 0 ( 19 | echo ERROR: %1 is required but was not found. 20 | set /a errors += 1 21 | ) 22 | 23 | goto :EOF 24 | 25 | :main 26 | 27 | for %%i in (sdk examples extras playground) do ( 28 | rem Environment variables in Windows aren't case-sensitive, so we don't need 29 | rem to bother with uppercasing the env var name. 30 | if exist "%~dp0pico-%%i" ( 31 | echo PICO_%%i_PATH=%~dp0pico-%%i 32 | set "PICO_%%i_PATH=%~dp0pico-%%i" 33 | ) 34 | ) 35 | 36 | if exist "%~dp0tools\openocd" ( 37 | echo OPENOCD_SCRIPTS=%~dp0tools\openocd\scripts 38 | set "OPENOCD_SCRIPTS=%~dp0tools\openocd\scripts" 39 | set "PATH=%~dp0tools\openocd;%PATH%" 40 | ) 41 | 42 | call :AddToPath "%ProgramFiles(x86)%\doxygen\bin" 43 | call :AddToPath "%ProgramFiles%\doxygen\bin" 44 | call :AddToPath "%ProgramW6432%\doxygen\bin" 45 | 46 | call :AddToPath "%ProgramFiles(x86)%\Graphviz\bin" 47 | call :AddToPath "%ProgramFiles%\Graphviz\bin" 48 | call :AddToPath "%ProgramW6432%\Graphviz\bin" 49 | 50 | call :AddToPath "%ProgramFiles(x86)%\Microsoft Visual Studio\Installer" 51 | call :AddToPath "%ProgramFiles%\Microsoft Visual Studio\Installer" 52 | 53 | rem https://github.com/microsoft/vswhere/wiki/Start-Developer-Command-Prompt 54 | 55 | for /f "usebackq delims=" %%i in (`vswhere.exe -products * -requires "Microsoft.VisualStudio.Component.VC.Tools.x86.x64" -latest -property installationPath`) do ( 56 | if exist "%%i\Common7\Tools\vsdevcmd.bat" ( 57 | call "%%i\Common7\Tools\vsdevcmd.bat" 58 | ) 59 | ) 60 | 61 | call :VerifyExe "GNU Arm Embedded Toolchain" "arm-none-eabi-gcc --version" 62 | call :VerifyExe "CMake" "cmake --version" 63 | call :VerifyExe "Visual Studio" "cl" 64 | call :VerifyExe "Python 3" "python --version" 65 | call :VerifyExe "Git" "git --version" 66 | 67 | exit /b %errors% 68 | -------------------------------------------------------------------------------- /pico-setup.cmd: -------------------------------------------------------------------------------- 1 | set interactive=%~1 2 | 3 | call "%~dp0pico-env.cmd" || exit /b 1 4 | setlocal enabledelayedexpansion 5 | 6 | rem This is mostly a port of pico-setup 7 | rem https://github.com/raspberrypi/pico-setup/blob/master/pico_setup.sh 8 | 9 | set "GITHUB_PREFIX=https://github.com/raspberrypi/" 10 | set "GITHUB_SUFFIX=.git" 11 | set "SDK_BRANCH=master" 12 | 13 | pushd "%~dp0" 14 | 15 | for %%i in (sdk examples extras playground project-generator) do ( 16 | set "DEST=%~dp0pico-%%i" 17 | 18 | if exist "!DEST!\.git" ( 19 | echo !DEST! exists, skipping clone 20 | ) else ( 21 | set "REPO_URL=%GITHUB_PREFIX%pico-%%i%GITHUB_SUFFIX%" 22 | echo Cloning !REPO_URL! 23 | git clone -b %SDK_BRANCH% !REPO_URL! || exit /b 1 24 | 25 | rem Any submodules 26 | pushd "!DEST!" 27 | git submodule update --init || exit /b 1 28 | popd 29 | 30 | set "PICO_%%i_PATH=!DEST!" 31 | ) 32 | ) 33 | 34 | rem Build a couple of examples 35 | mkdir "%~dp0pico-examples\build" 36 | pushd "%~dp0pico-examples\build" 37 | cmake -G "NMake Makefiles" .. -DCMAKE_BUILD_TYPE=Debug || exit /b 1 38 | 39 | for %%i in (blink hello_world) do ( 40 | echo Building %%i 41 | pushd %%i 42 | nmake || exit /b 1 43 | popd 44 | ) 45 | 46 | popd 47 | 48 | if exist "%~dp0pico-docs.ps1" ( 49 | echo Downloading Pico documents and files... 50 | powershell -NoProfile -NonInteractive -ExecutionPolicy Bypass -File "%~dp0pico-docs.ps1" || exit /b 1 51 | ) 52 | 53 | if "%interactive%" equ "1" ( 54 | rem Open repo folder in Explorer 55 | start . 56 | 57 | rem Keep the terminal window open 58 | pause 59 | ) 60 | 61 | popd 62 | -------------------------------------------------------------------------------- /tests/common.Tests.ps1: -------------------------------------------------------------------------------- 1 | BeforeAll { 2 | Set-StrictMode -Version Latest 3 | $ErrorActionPreference = 'Stop' 4 | 5 | . "$PSScriptRoot\..\common.ps1" 6 | } 7 | 8 | Describe 'exec' { 9 | It 'Should run native command' { 10 | exec { cmd /c echo Hello world! } | Should -Be 'Hello world!' 11 | } 12 | 13 | It 'Should capture stderr' { 14 | exec { cmd /c "echo Oops 1>&2" } | Should -Be 'Oops ' 15 | } 16 | 17 | It 'Should throw on non-zero exit code' { 18 | { exec { cmd /c exit 42 } } | Should -Throw 19 | } 20 | 21 | It 'Should not clobber a variable named cmd' { 22 | $cmd = 'Yes' 23 | exec { cmd /c "echo $cmd" } | Should -Be 'Yes' 24 | } 25 | 26 | It 'Should throw on script errors' { 27 | { exec { xyzzy } } | Should -Throw 28 | } 29 | } 30 | 31 | Describe 'mkdirp' { 32 | It 'Should create directory tree' { 33 | $targetRoot = Join-Path ([IO.Path]::GetTempPath()) (New-Guid) 34 | $target = Join-Path $targetRoot "a\b\c" 35 | 36 | mkdirp $target 37 | 38 | Test-Path $target -PathType Container | Should -BeTrue 39 | Remove-Item $targetRoot -Recurse 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /tests/setup-oldvs.ps1: -------------------------------------------------------------------------------- 1 | # Install an older version of Visual Studio 2019 Build Tools, for testing if the installer can 2 | # properly modify an existing install to add the Visual C++ tools needed. 3 | 4 | Set-StrictMode -Version Latest 5 | $ErrorActionPreference = 'Stop' 6 | $ProgressPreference = 'SilentlyContinue' 7 | 8 | . "$PSScriptRoot\..\common.ps1" 9 | 10 | # BuildTools 16.4.24 from https://docs.microsoft.com/en-us/visualstudio/releases/2019/history 11 | $href = "https://download.visualstudio.microsoft.com/download/pr/755cef87-e337-468d-bc48-7c0426929076/90deefbf24f4a074ea9df5ee42c56152f7a57229655fe4d44477a32bb0a23d55/vs_BuildTools.exe" 12 | $file = "vs_BuildTools.exe" 13 | 14 | Write-Host "Downloading $file" 15 | exec { curl.exe --fail --silent --show-error --url $href --location --output "installers/$file" --create-dirs } 16 | 17 | Write-Host "Starting $file" 18 | $process = $null 19 | $elapsed = Measure-Command { $process = Start-Process -FilePath ".\installers\$file" -ArgumentList '--add Microsoft.VisualStudio.Workload.DataBuildTools --quiet --wait --norestart' -Wait -PassThru } 20 | Write-Host ("Finished in {0:hh':'mm':'ss}" -f $elapsed) 21 | 22 | if ($process.ExitCode -ne 0) { 23 | throw "Install failed with exit code $($process.ExitCode)" 24 | exit $process.ExitCode 25 | } 26 | -------------------------------------------------------------------------------- /tests/setup.ps1: -------------------------------------------------------------------------------- 1 | Set-StrictMode -Version Latest 2 | $ErrorActionPreference = 'Stop' 3 | $ProgressPreference = 'SilentlyContinue' 4 | 5 | . "$PSScriptRoot\..\common.ps1" 6 | 7 | $installer = Get-ChildItem bin\*.exe | Select-Object -First 1 -ExpandProperty FullName 8 | Write-Host "Starting $installer" 9 | $elapsed = Measure-Command { Start-Process -FilePath $installer -ArgumentList "/S" -Wait } 10 | Write-Host ("Finished in {0:hh':'mm':'ss}" -f $elapsed) 11 | 12 | $installPath = "$([Environment]::GetFolderPath("MyDocuments"))\Pico" 13 | 14 | Write-Host "Copying logs" 15 | mkdirp logs 16 | Copy-Item $env:TEMP\dd_*.log .\logs 17 | Copy-Item "$installPath\install.log" .\logs 18 | 19 | exec { cmd /c call "$env:TEMP\RefreshEnv.cmd" "&&" call "$installPath\pico-setup.cmd" } 20 | -------------------------------------------------------------------------------- /tools.json: -------------------------------------------------------------------------------- 1 | { 2 | "tools": [ 3 | { 4 | "name": "NSIS", 5 | "file": "nsis.zip", 6 | "href": "https://sourceforge.net/projects/nsis/files/NSIS%203/3.08/nsis-3.08.zip/download" 7 | }, 8 | { 9 | "name": "NSIS with logging", 10 | "file": "nsis-log.zip", 11 | "href": "https://sourceforge.net/projects/nsis/files/NSIS%203/3.08/nsis-3.08-log.zip/download" 12 | }, 13 | { 14 | "name": "MSYS2", 15 | "file": "msys2.exe", 16 | "href": "https://github.com/msys2/msys2-installer/releases/download/2022-10-28/msys2-base-x86_64-20221028.sfx.exe" 17 | }, 18 | { 19 | "name": "vswhere", 20 | "file": "vswhere.exe", 21 | "href": "https://github.com/microsoft/vswhere/releases/download/3.1.1/vswhere.exe" 22 | } 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /update.ps1: -------------------------------------------------------------------------------- 1 | #Requires -Version 7.0 2 | Set-StrictMode -Version Latest 3 | $ErrorActionPreference = 'Stop' 4 | $ProgressPreference = 'SilentlyContinue' 5 | 6 | . "$PSScriptRoot\common.ps1" 7 | 8 | function getGitHubReleaseAssetUrl { 9 | param ( 10 | [string] $Repo, 11 | [scriptblock] $AssetFilter, 12 | [scriptblock] $ReleaseFilter = { $_.prerelease -eq $false } 13 | ) 14 | 15 | $rel = (Invoke-RestMethod "https://api.github.com/repos/$Repo/releases") | 16 | Where-Object $ReleaseFilter | 17 | Select-Object -First 1 18 | $asset = $rel.assets | 19 | Where-Object $AssetFilter 20 | $asset.browser_download_url 21 | } 22 | 23 | function updateDownloadUrl { 24 | param ( 25 | $Download, 26 | $Config 27 | ) 28 | 29 | Write-Host "Updating $($Download.name): " -NoNewline 30 | 31 | $newName = $null # Override local filename if needed 32 | 33 | [uri]$newUrl = switch ($Download.name) { 34 | 35 | 'GNU Arm Embedded Toolchain' { 36 | crawl 'https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads' | 37 | Where-Object { $_ -match "-win32\.exe" } | # There is no 64-bit build for Windows currently 38 | Select-Object -First 1 39 | } 40 | 41 | 'CMake' { 42 | $suffix = $Config.bitness -eq 64 ? 'x86_64' : 'i386' 43 | 44 | # CMake does not mark prereleases as such, so we filter based on the tag 45 | getGitHubReleaseAssetUrl 'Kitware/CMake' { $_.name -match "windows-$suffix\.msi`$" } { $_.tag_name -match '^v([0-9]+\.)+[0-9]$' } 46 | } 47 | 48 | 'Python 3.9' { 49 | $suffix = $Config.bitness -eq 64 ? '-amd64' : '' 50 | 51 | crawl 'https://www.python.org/downloads/windows/' | 52 | Where-Object { $_ -match "python-3\.9\.[0-9]+$suffix\.exe`$" } | 53 | Select-Object -First 1 54 | } 55 | 56 | 'Git for Windows' { 57 | getGitHubReleaseAssetUrl 'git-for-windows/git' { $_.name -match "^Git-([0-9]+\.)+[0-9]+-$($Config.bitness)-bit\.exe`$" } 58 | } 59 | 60 | 'Doxygen' { 61 | crawl 'https://www.doxygen.nl/download.html' | 62 | Where-Object { $_ -match "-setup\.exe" } | 63 | Select-Object -First 1 64 | } 65 | 66 | 'Graphviz' { 67 | $link = (Invoke-WebRequest 'https://graphviz.org/download/' -UseBasicParsing).Links | 68 | Where-Object { $_.outerHTML -match "-win$($Config.bitness)\.exe" } | 69 | Select-Object -First 1 70 | if ($link.outerHTML -match '[a-zA-Z0-9_\-\.]+\.exe') { 71 | $newName = $Matches[0] 72 | $link.href 73 | } 74 | } 75 | 76 | 'NSIS' { 77 | $newName = 'nsis.zip' 78 | $item = Invoke-RestMethod 'https://sourceforge.net/projects/nsis/rss' | 79 | Where-Object { $_.link -match 'nsis-([0-9]+\.)+[0-9]+\.zip' } | 80 | Select-Object -First 1 81 | $item.link 82 | } 83 | 84 | 'NSIS with logging' { 85 | $newName = 'nsis-log.zip' 86 | $item = Invoke-RestMethod 'https://sourceforge.net/projects/nsis/rss' | 87 | Where-Object { $_.link -match 'nsis-([0-9]+\.)+[0-9]+\-log.zip' } | 88 | Select-Object -First 1 89 | $item.link 90 | } 91 | 92 | 'MSYS2' { 93 | $newName = 'msys2.exe' 94 | getGitHubReleaseAssetUrl 'msys2/msys2-installer' { $_.name -match "^msys2-base-x86_64-[0-9]+\.sfx\.exe`$" } 95 | } 96 | 97 | 'vswhere' { 98 | $newName = 'vswhere.exe' 99 | getGitHubReleaseAssetUrl 'microsoft/vswhere' { $_.name -eq 'vswhere.exe' } 100 | } 101 | } 102 | 103 | if ($newUrl) { 104 | $newName ??= $newUrl.Segments[-1] 105 | 106 | Write-Host $newName 107 | 108 | $Download.file = $newName 109 | $Download.href = $newUrl.AbsoluteUri 110 | } else { 111 | Write-Host "No update" 112 | } 113 | } 114 | 115 | foreach ($arch in @('x86.json', 'x64.json')) { 116 | $config = Get-Content $arch | ConvertFrom-Json 117 | 118 | foreach ($i in $config.installers) { 119 | updateDownloadUrl $i $config 120 | } 121 | 122 | $config | ConvertTo-Json -Depth 3 | Set-Content $arch 123 | } 124 | 125 | $tools = Get-Content '.\tools.json' | ConvertFrom-Json 126 | 127 | foreach ($i in $tools.tools) { 128 | updateDownloadUrl $i $tools 129 | } 130 | 131 | $tools | ConvertTo-Json -Depth 3 | Set-Content '.\tools.json' 132 | -------------------------------------------------------------------------------- /version.txt: -------------------------------------------------------------------------------- 1 | 0.3.5 2 | -------------------------------------------------------------------------------- /vssetup.ps1: -------------------------------------------------------------------------------- 1 | param ( 2 | [ValidateNotNullOrEmpty()] 3 | [string] 4 | $VSInstallerPath = '.\installers\vs_BuildTools.exe', 5 | 6 | [ValidateNotNullOrEmpty()] 7 | [string] 8 | $VSWherePath = '.\installers\vswhere.exe' 9 | ) 10 | 11 | Set-StrictMode -Version Latest 12 | $ErrorActionPreference = 'Stop' 13 | $ProgressPreference = 'SilentlyContinue' 14 | 15 | $installerVersion = [version](Get-Item $VSInstallerPath).VersionInfo.FileVersion 16 | $interval = "[{0},{1})" -f $installerVersion.Major, ($installerVersion.Major + 1) 17 | 18 | $VSInstallerPath -match 'vs_([a-zA-Z]+).exe' | Out-Null 19 | $product = $Matches[1] 20 | 21 | Write-Host "Looking for existing Visual Studio $product installs: " -NoNewline 22 | $modify = "" 23 | $existingInstallPath = & $VSWherePath -products "Microsoft.VisualStudio.Product.$product" -version $interval -latest -property installationPath 24 | if ($existingInstallPath) { 25 | $modify = "modify --installPath `"$existingInstallPath`"" 26 | Write-Host $existingInstallPath 27 | } 28 | else { 29 | Write-Host "not found" 30 | } 31 | 32 | $installArgs = "$modify --add Microsoft.VisualStudio.Workload.VCTools --includeRecommended --quiet --wait --norestart" 33 | Write-Host "Starting $VSInstallerPath $installArgs" 34 | $process = Start-Process -FilePath $VSInstallerPath -ArgumentList $installArgs -Wait -PassThru 35 | exit $process.ExitCode 36 | -------------------------------------------------------------------------------- /x64.json: -------------------------------------------------------------------------------- 1 | { 2 | "bitness": 64, 3 | "mingw_arch": "x86_64", 4 | "installers": [ 5 | { 6 | "name": "GNU Arm Embedded Toolchain", 7 | "file": "gcc-arm-none-eabi-10.3-2021.10-win32.exe", 8 | "exec": "\"$0\" /S /P /R", 9 | "href": "https://developer.arm.com/-/media/Files/downloads/gnu-rm/10.3-2021.10/gcc-arm-none-eabi-10.3-2021.10-win32.exe?rev=29bb46cfa0434fbda93abb33c1d480e6&hash=B2C5AAE07841929A0D0BF460896D6E52" 10 | }, 11 | { 12 | "name": "CMake", 13 | "file": "cmake-3.25.0-windows-x86_64.msi", 14 | "exec": "msiexec /i \"$0\" /qn /norestart ADD_CMAKE_TO_PATH=System", 15 | "href": "https://github.com/Kitware/CMake/releases/download/v3.25.0/cmake-3.25.0-windows-x86_64.msi" 16 | }, 17 | { 18 | "name": "Build Tools for Visual Studio 2019", 19 | "file": "vs_BuildTools.exe", 20 | "exec": "powershell -NoProfile -ExecutionPolicy Bypass -WindowStyle Minimized -File \"$PLUGINSDIR\\vssetup.ps1\" -VSInstallerPath \"$0\" -VSWherePath \"$PLUGINSDIR\\vswhere.exe\"", 21 | "href": "https://aka.ms/vs/16/release/vs_buildtools.exe", 22 | "additionalFiles": [ 23 | "installers\\vswhere.exe", 24 | "vssetup.ps1" 25 | ], 26 | "rebootExitCodes": [ 27 | 3010 28 | ] 29 | }, 30 | { 31 | "name": "Python 3.9", 32 | "file": "python-3.9.13-amd64.exe", 33 | "exec": "\"$0\" /quiet InstallAllUsers=1 PrependPath=1", 34 | "href": "https://www.python.org/ftp/python/3.9.13/python-3.9.13-amd64.exe" 35 | }, 36 | { 37 | "name": "Git for Windows", 38 | "file": "Git-2.38.1-64-bit.exe", 39 | "exec": "\"$0\" /VERYSILENT /NORESTART /NOCANCEL /SP- /CLOSEAPPLICATIONS /RESTARTAPPLICATIONS /SKIPDOWNGRADE=1 \"/LOADINF=$PLUGINSDIR\\git.inf\"", 40 | "href": "https://github.com/git-for-windows/git/releases/download/v2.38.1.windows.1/Git-2.38.1-64-bit.exe", 41 | "additionalFiles": [ 42 | "git.inf" 43 | ] 44 | }, 45 | { 46 | "name": "Visual Studio Code", 47 | "file": "VSCodeUserSetup-x64.exe", 48 | "exec": "\"$0\" /VERYSILENT /NORESTART /NOCANCEL /SP- /CLOSEAPPLICATIONS /RESTARTAPPLICATIONS /MERGETASKS=!runcode", 49 | "href": "https://code.visualstudio.com/sha/download?build=stable&os=win32-x64-user" 50 | }, 51 | { 52 | "name": "Doxygen", 53 | "file": "doxygen-1.9.5-setup.exe", 54 | "exec": "\"$0\" /VERYSILENT /NORESTART /NOCANCEL /SP- /CLOSEAPPLICATIONS /RESTARTAPPLICATIONS", 55 | "href": "https://www.doxygen.nl/files/doxygen-1.9.5-setup.exe" 56 | }, 57 | { 58 | "name": "Graphviz", 59 | "file": "windows_10_cmake_Release_graphviz-install-7.0.1-win64.exe", 60 | "exec": "\"$0\" /S", 61 | "href": "https://gitlab.com/api/v4/projects/4207231/packages/generic/graphviz-releases/7.0.1/windows_10_cmake_Release_graphviz-install-7.0.1-win64.exe" 62 | } 63 | ] 64 | } 65 | -------------------------------------------------------------------------------- /x86.json: -------------------------------------------------------------------------------- 1 | { 2 | "bitness": 32, 3 | "mingw_arch": "i686", 4 | "installers": [ 5 | { 6 | "name": "GNU Arm Embedded Toolchain", 7 | "file": "gcc-arm-none-eabi-10.3-2021.10-win32.exe", 8 | "exec": "\"$0\" /S /P /R", 9 | "href": "https://developer.arm.com/-/media/Files/downloads/gnu-rm/10.3-2021.10/gcc-arm-none-eabi-10.3-2021.10-win32.exe?rev=29bb46cfa0434fbda93abb33c1d480e6&hash=B2C5AAE07841929A0D0BF460896D6E52" 10 | }, 11 | { 12 | "name": "CMake", 13 | "file": "cmake-3.25.0-windows-i386.msi", 14 | "exec": "msiexec /i \"$0\" /qn /norestart ADD_CMAKE_TO_PATH=System", 15 | "href": "https://github.com/Kitware/CMake/releases/download/v3.25.0/cmake-3.25.0-windows-i386.msi" 16 | }, 17 | { 18 | "name": "Build Tools for Visual Studio 2019", 19 | "file": "vs_BuildTools.exe", 20 | "exec": "powershell -NoProfile -ExecutionPolicy Bypass -WindowStyle Minimized -File \"$PLUGINSDIR\\vssetup.ps1\" -VSInstallerPath \"$0\" -VSWherePath \"$PLUGINSDIR\\vswhere.exe\"", 21 | "href": "https://aka.ms/vs/16/release/vs_buildtools.exe", 22 | "additionalFiles": [ 23 | "installers\\vswhere.exe", 24 | "vssetup.ps1" 25 | ], 26 | "rebootExitCodes": [ 27 | 3010 28 | ] 29 | }, 30 | { 31 | "name": "Python 3.9", 32 | "file": "python-3.9.13.exe", 33 | "exec": "\"$0\" /quiet InstallAllUsers=1 PrependPath=1", 34 | "href": "https://www.python.org/ftp/python/3.9.13/python-3.9.13.exe" 35 | }, 36 | { 37 | "name": "Git for Windows", 38 | "file": "Git-2.38.1-32-bit.exe", 39 | "exec": "\"$0\" /VERYSILENT /NORESTART /NOCANCEL /SP- /CLOSEAPPLICATIONS /RESTARTAPPLICATIONS /SKIPDOWNGRADE=1 \"/LOADINF=$PLUGINSDIR\\git.inf\"", 40 | "href": "https://github.com/git-for-windows/git/releases/download/v2.38.1.windows.1/Git-2.38.1-32-bit.exe", 41 | "additionalFiles": [ 42 | "git.inf" 43 | ] 44 | }, 45 | { 46 | "name": "Visual Studio Code", 47 | "file": "VSCodeUserSetup-ia32.exe", 48 | "exec": "\"$0\" /VERYSILENT /NORESTART /NOCANCEL /SP- /CLOSEAPPLICATIONS /RESTARTAPPLICATIONS /MERGETASKS=!runcode", 49 | "href": "https://code.visualstudio.com/sha/download?build=stable&os=win32-user" 50 | }, 51 | { 52 | "name": "Doxygen", 53 | "file": "doxygen-1.9.5-setup.exe", 54 | "exec": "\"$0\" /VERYSILENT /NORESTART /NOCANCEL /SP- /CLOSEAPPLICATIONS /RESTARTAPPLICATIONS", 55 | "href": "https://www.doxygen.nl/files/doxygen-1.9.5-setup.exe" 56 | }, 57 | { 58 | "name": "Graphviz", 59 | "file": "windows_10_cmake_Release_graphviz-install-7.0.1-win32.exe", 60 | "exec": "\"$0\" /S", 61 | "href": "https://gitlab.com/api/v4/projects/4207231/packages/generic/graphviz-releases/7.0.1/windows_10_cmake_Release_graphviz-install-7.0.1-win32.exe" 62 | } 63 | ] 64 | } 65 | --------------------------------------------------------------------------------