# Instala (ou atualiza) o Doca no Windows 10/11, sem admin e sem aviso do SmartScreen: # # irm https://doca.racoelho.com.br/instalar.ps1 | iex # # Lê versao.json no site, baixa o instalador da sua plataforma (x64 ou ARM64), confere o SHA-256 # e roda em silêncio. É o mesmo instalador do botão de # download: vai para %LOCALAPPDATA%\Programs\Doca, com atalho no Iniciar e "Desinstalar" em # Configurações › Aplicativos. Rodar de novo atualiza por cima; os ambientes e ajustes # (%LOCALAPPDATA%\Doca) ficam. DOCA_SEM_ABRIR=1 instala sem abrir o Doca no fim. # # Para quem comprou, a página de obrigado e o e-mail da chave trazem o comando com a chave, que # instala e já ativa: $env:DOCA_CHAVE='DOCA-…'; irm https://doca.racoelho.com.br/instalar.ps1 | iex & { $ErrorActionPreference = "Stop" $ProgressPreference = "SilentlyContinue" [Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12 $site = "https://doca.racoelho.com.br" $temp = Join-Path $env:TEMP ("doca-instalar-" + [guid]::NewGuid().ToString("N")) function Passo($texto) { Write-Host " $texto" -ForegroundColor Cyan } try { Write-Host "" Write-Host "Doca" -ForegroundColor White # A arquitetura do Windows (não a do PowerShell, que pode ser 32 bits ou emulado). Em alguns # PowerShell o RuntimeInformation volta vazio; aí valem as variáveis do próprio Windows. $arq = "" try { $arq = "$([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture)" } catch { } if (-not $arq) { $arq = if ($env:PROCESSOR_ARCHITEW6432) { "$env:PROCESSOR_ARCHITEW6432" } else { "$env:PROCESSOR_ARCHITECTURE" } } $plat = switch -Regex ($arq) { "^(arm64)$" { "arm64"; break } "^(x64|amd64)$" { "x64"; break } default { throw "O Doca roda em Windows x64 ou ARM64 (este é '$arq')." } } if ([Environment]::OSVersion.Version.Build -lt 19041) { throw "O Doca precisa do Windows 10 versão 2004 ou mais novo." } Passo "Procurando a versão mais nova…" $info = Invoke-RestMethod "$site/doca/version.json?t=$([DateTimeOffset]::UtcNow.ToUnixTimeSeconds())" -Headers @{ "Cache-Control" = "no-cache" } $pacote = $info.$plat if (-not $pacote -or -not $pacote.url) { throw "Ainda não há instalador para $plat." } New-Item -ItemType Directory -Force $temp | Out-Null $setup = Join-Path $temp "Doca-$($info.versao)-$plat-setup.exe" Passo "Baixando o Doca $($info.versao) ($plat)…" # Pelo /doca/download do site, que conta o download e leva ao mesmo instalador do GitHub. Se ele # falhar (ou entregar outra versão, se uma saiu agora), baixa direto do GitHub. $esperado = "$($pacote.sha256)".ToUpperInvariant() $contado = "$site/doca/download?canal=comando" + $(if ($plat -eq "arm64") { "&arm64" } else { "" }) try { Invoke-WebRequest $contado -OutFile $setup -UseBasicParsing } catch { } if (-not (Test-Path $setup) -or (Get-FileHash $setup -Algorithm SHA256).Hash -ne $esperado) { $direto = if ($pacote.github) { $pacote.github } else { $pacote.url } Invoke-WebRequest $direto -OutFile $setup -UseBasicParsing } $hash = (Get-FileHash $setup -Algorithm SHA256).Hash if ($hash -ne $esperado) { throw "O arquivo baixado não confere (SHA-256 diferente). Tente de novo." } # Um Doca aberto como administrador (de um Terminal de administrador) não pode ser fechado # por este instalador, que roda sem privilégio: os arquivos ficariam presos. $aberto = @(Get-Process Doca -ErrorAction SilentlyContinue) $semAcesso = @($aberto | Where-Object { -not $_.Path }) if ($semAcesso.Count -gt 0 -and -not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) { throw "O Doca está aberto como administrador, e este Terminal não consegue fechá-lo. Feche o Doca (botão direito no dock › Sair) e rode o comando de novo." } Passo "Instalando…" $p = Start-Process -FilePath $setup -ArgumentList "/VERYSILENT", "/SUPPRESSMSGBOXES", "/NORESTART", "/SP-" -Wait -PassThru if ($p.ExitCode -eq 5) { throw "Algum arquivo do Doca estava em uso. Feche o Doca (botão direito no dock › Sair) e rode o comando de novo." } if ($p.ExitCode -ne 0) { throw "O instalador terminou com erro ($($p.ExitCode))." } $exe = Join-Path $env:LOCALAPPDATA "Programs\Doca\Doca.exe" # Comprou? O comando da página de obrigado traz a chave ($env:DOCA_CHAVE): ela já entra # ativada, sem precisar colar nos Ajustes. O Doca confere a assinatura ao abrir. $chave = "$env:DOCA_CHAVE" -replace "\s", "" if ($chave) { if ($chave -notmatch "^DOCA-[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$") { throw "A chave não parece completa. Copie o comando de novo da página ou do e-mail." } $pastaDados = Join-Path $env:LOCALAPPDATA "Doca" $arquivo = Join-Path $pastaDados "licenca.json" $dados = [ordered]@{} if (Test-Path $arquivo) { try { (Get-Content $arquivo -Raw | ConvertFrom-Json).PSObject.Properties | ForEach-Object { $dados[$_.Name] = $_.Value } } catch { } } $dados["chave"] = $chave New-Item -ItemType Directory -Force $pastaDados | Out-Null [IO.File]::WriteAllText($arquivo, ($dados | ConvertTo-Json), (New-Object System.Text.UTF8Encoding $false)) Remove-Item Env:\DOCA_CHAVE -ErrorAction SilentlyContinue Passo "Licença ativada." } Write-Host "" Write-Host " Doca $($info.versao) instalado." -ForegroundColor Green Write-Host " Para desinstalar: Configurações › Aplicativos › Doca." -ForegroundColor DarkGray if ($env:DOCA_SEM_ABRIR -ne "1" -and (Test-Path $exe)) { Passo "Abrindo o Doca…" # Pelo Explorer: o Doca abre como o usuário comum, mesmo se este Terminal for de # administrador (um Doca de administrador não deixaria a próxima atualização fechá-lo). Start-Process -FilePath (Join-Path $env:windir "explorer.exe") -ArgumentList "`"$exe`"" } Write-Host "" } catch { Write-Host "" Write-Host " Não deu para instalar: $($_.Exception.Message)" -ForegroundColor Red Write-Host " (detalhe para o suporte: linha $($_.InvocationInfo.ScriptLineNumber), PowerShell $($PSVersionTable.PSVersion))" -ForegroundColor DarkGray Write-Host " Tente de novo, ou baixe o instalador em $site/direto#instalar" -ForegroundColor DarkGray Write-Host "" } finally { if (Test-Path $temp) { Remove-Item $temp -Recurse -Force -ErrorAction SilentlyContinue } } }