Poperton
Poperton

Reputation: 2147

How can I install CMake with PowerShell? (automatic installation)

I want to install CMake without any interaction. I tried this script, but there's no Install-FromMsi on my PowerShell.

Is there a fix for that or an easier way to install CMake and put it into the PowerShell path just with scripts?

PS: how to call Install-CMake with parameters?

UPDATE:

I followed https://silentinstallhq.com/cmake-silent-install-how-to-guide/ and tried

Write-Host "Installing Cmake..." -ForegroundColor Cyan
$exePath = "$env:TEMP\cmake.exe"

Write-Host "Downloading..."
(New-Object Net.WebClient).DownloadFile('https://github.com/Kitware/CMake/releases/download/v3.24.0/cmake-3.24.0-windows-x86_64.msi', $exePath)

Write-Host "Installing..."
MsiExec.exe /i $exePath ADD_CMAKE_TO_PATH=User /qn

but my Windows does not recognize the command MsiExec.exe

I changed to

Start-Process msiexec.exe -Wait -ArgumentList "/i $exePath ADD_CMAKE_TO_PATH=User /qn"

cmake --version

It looks like it installs but cmake --version says that cmake is not a command in PowerShell, so either it's not installing or not putting into PATH.

Upvotes: 3

Views: 8709

Answers (1)

stackprotector
stackprotector

Reputation: 13452

ADD_CMAKE_TO_PATH=User does what it should do, but there are two problems in your case:

  1. You have to wait until msiexec.exe finishes. To do that, either pipe the result of the direct invocation to somewhere:

    msiexec.exe /i $exePath ADD_CMAKE_TO_PATH=User /qn | Out-Null
    

    Or use Start-Process with the -Wait parameter (which you already did):

    Start-Process msiexec.exe -ArgumentList "/i $exePath ADD_CMAKE_TO_PATH=User /qn" -Wait
    

    You can read more about that in this Q&A.

  2. When you update the environment variables of the Machine or User scope, existing processes will not inherit them into their existing Process scope. That's why your already running PowerShell process still does not know cmake after its installation. You can read more about that in this Q&A.

    You either have to start a really new PowerShell process (see above linked Q&A) or you have to reimport the environement variables of the Machine and User scope into your Process scope:

    foreach($level in "Machine","User") {
       [Environment]::GetEnvironmentVariables($level).GetEnumerator() | % {
          # For Path variables, append the new values, if they're not already in there
          if($_.Name -match 'Path$') { 
             $_.Value = ($((Get-Content "Env:$($_.Name)") + ";$($_.Value)") -split ';' | Select -unique) -join ';'
          }
          $_
       } | Set-Content -Path { "Env:$($_.Name)" }
    }
    

    This code is taken from this answer.

    After that, cmake --version and Get-Command cmake will work.


Side notes:

  • If Start-Process can find msiexec.exe, then the direct invocation should also work. Maybe you just had a typo, when trying that.

  • A more PowerShelly way to download a file is:

    Invoke-WebRequest -Uri https://github.com/Kitware/CMake/releases/download/v3.24.0/cmake-3.24.0-windows-x86_64.msi -UseBasicParsing -OutFile $exePath
    

Upvotes: 2

Related Questions