Eerste commit
This commit is contained in:
@@ -0,0 +1,221 @@
|
||||
<#
|
||||
Maakt een APK van de Android-app.
|
||||
|
||||
Draaien vanaf je eigen pc:
|
||||
D:\MijnBesluit\tools\Apk-maken.ps1 # release-APK, ondertekend
|
||||
D:\MijnBesluit\tools\Apk-maken.ps1 -Snel # snel, met de debug-sleutel
|
||||
D:\MijnBesluit\tools\Apk-maken.ps1 -Aab # bundel voor de Play Store
|
||||
|
||||
De eerste keer maakt het script een sleutelbestand aan (een "keystore"). Bewaar dat goed:
|
||||
zonder dat bestand kun je later geen nieuwe versie van de app meer uitbrengen die Android
|
||||
als dezelfde app herkent. Dat is niet te herstellen — net zo min als het sleutelbestand
|
||||
van de kluis.
|
||||
#>
|
||||
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
# Bouwt een debug-versie met de standaard debug-sleutel: meteen te installeren op je eigen
|
||||
# toestel. Heet bewust niet -Debug: die naam is van PowerShell zelf.
|
||||
[switch] $Snel,
|
||||
|
||||
# Bouwt een AAB in plaats van een APK. Dat is wat de Play Store wil: een bundel waaruit
|
||||
# Google per toestel een APK maakt, zodat niemand de onderdelen voor andere toestellen
|
||||
# meedownloadt. Een AAB kun je niet zelf op een telefoon zetten - daarvoor blijf je de APK
|
||||
# gebruiken. Zelfde sleutelbestand, zelfde wachtwoord.
|
||||
[switch] $Aab,
|
||||
|
||||
# Waar de APK terechtkomt.
|
||||
[string] $Uit = 'D:\publish\mijnbesluit-app',
|
||||
|
||||
# Het sleutelbestand waarmee de app wordt ondertekend.
|
||||
[string] $Sleutelbestand = 'D:\MijnBesluitSleutels\mijnbesluit-app.keystore',
|
||||
[string] $Alias = 'mijnbesluit',
|
||||
|
||||
# Alleen invullen als het script keytool.exe niet zelf kan vinden.
|
||||
[string] $Keytool
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
$project = Join-Path $PSScriptRoot '..\src\MijnBesluit.App\MijnBesluit.App.csproj' | Resolve-Path
|
||||
$doel = 'net10.0-android'
|
||||
|
||||
New-Item -ItemType Directory -Path $Uit -Force | Out-Null
|
||||
|
||||
if ($Snel) {
|
||||
Write-Host "APK bouwen (debug)..." -ForegroundColor Cyan
|
||||
|
||||
# EmbedAssembliesIntoApk: bij Debug laat MAUI de .NET-assemblies normaal buiten het pakket,
|
||||
# omdat Visual Studio ze bij het debuggen los naar het toestel duwt. Een APK die je met de
|
||||
# hand installeert mist ze dan, en de app klapt bij het starten meteen dicht.
|
||||
dotnet build $project -f $doel -c Debug -p:EmbedAssembliesIntoApk=true
|
||||
if ($LASTEXITCODE -ne 0) { throw "Bouwen mislukt." }
|
||||
|
||||
$apk = Get-ChildItem (Join-Path (Split-Path $project) "bin\Debug\$doel") -Filter '*-Signed.apk' |
|
||||
Sort-Object LastWriteTime -Descending | Select-Object -First 1
|
||||
if (-not $apk) { throw "Geen APK gevonden. Staat de MAUI-werkbelasting geinstalleerd?" }
|
||||
|
||||
Copy-Item $apk.FullName (Join-Path $Uit 'mijnbesluit-debug.apk') -Force
|
||||
Write-Host "Klaar: $Uit\mijnbesluit-debug.apk" -ForegroundColor Green
|
||||
return
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------ keytool zoeken
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Zoekt keytool.exe, dat bij de Java hoort die met de Android-werkbelasting meekomt.
|
||||
|
||||
.DESCRIPTION
|
||||
Waar die Java staat hangt af van hoe Visual Studio is geinstalleerd - er zijn er een stuk
|
||||
of vijf in omloop. Daarom kijken we op alle bekende plekken in plaats van op een.
|
||||
#>
|
||||
function Vind-Keytool
|
||||
{
|
||||
if ($Keytool) {
|
||||
if (-not (Test-Path $Keytool)) { throw "Opgegeven keytool bestaat niet: $Keytool" }
|
||||
return $Keytool
|
||||
}
|
||||
|
||||
$inPad = Get-Command keytool -ErrorAction SilentlyContinue
|
||||
if ($inPad) { return $inPad.Source }
|
||||
|
||||
$plekken = @()
|
||||
|
||||
if ($env:JAVA_HOME) { $plekken += (Join-Path $env:JAVA_HOME 'bin\keytool.exe') }
|
||||
|
||||
$mappen = @(
|
||||
'C:\Program Files\Microsoft\jdk-*',
|
||||
'C:\Program Files\Android\openjdk\*',
|
||||
'C:\Program Files\Android\jdk\*',
|
||||
'C:\Program Files (x86)\Android\openjdk\*',
|
||||
'C:\Program Files (x86)\Android\jdk\*',
|
||||
'C:\Program Files\Eclipse Adoptium\jdk-*',
|
||||
'C:\Program Files\Java\jdk-*',
|
||||
"$env:LOCALAPPDATA\Android\jdk\*"
|
||||
)
|
||||
|
||||
foreach ($map in $mappen) {
|
||||
Get-ChildItem $map -Directory -ErrorAction SilentlyContinue |
|
||||
Sort-Object Name -Descending |
|
||||
ForEach-Object { $plekken += (Join-Path $_.FullName 'bin\keytool.exe') }
|
||||
}
|
||||
|
||||
# Android Studio brengt zijn eigen Java mee.
|
||||
$plekken += 'C:\Program Files\Android\Android Studio\jbr\bin\keytool.exe'
|
||||
|
||||
foreach ($pad in $plekken) {
|
||||
if (Test-Path $pad) { return $pad }
|
||||
}
|
||||
|
||||
throw @"
|
||||
keytool.exe is nergens gevonden. Dat hoort bij de Java die met de Android-werkbelasting meekomt.
|
||||
|
||||
Gezocht in:
|
||||
$($plekken -join "`n")
|
||||
|
||||
Zoek hem zelf met:
|
||||
Get-ChildItem 'C:\Program Files','C:\Program Files (x86)' -Recurse -Filter keytool.exe -ErrorAction SilentlyContinue |
|
||||
Select-Object -First 5 FullName
|
||||
|
||||
Zet de map met keytool.exe daarna in JAVA_HOME, of geef het pad mee met -Keytool.
|
||||
|
||||
Wil je alleen op je eigen toestel testen, gebruik dan -Snel: een debug-APK heeft dit niet nodig.
|
||||
"@
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------ release
|
||||
|
||||
if (-not (Test-Path $Sleutelbestand)) {
|
||||
Write-Host "Er is nog geen sleutelbestand. Ik maak er een aan." -ForegroundColor Yellow
|
||||
Write-Host "Kies een wachtwoord dat je NIET kwijtraakt." -ForegroundColor Yellow
|
||||
|
||||
$keytool = Vind-Keytool
|
||||
|
||||
New-Item -ItemType Directory -Path (Split-Path $Sleutelbestand) -Force | Out-Null
|
||||
|
||||
& $keytool -genkeypair -v `
|
||||
-keystore $Sleutelbestand -alias $Alias `
|
||||
-keyalg RSA -keysize 2048 -validity 10000
|
||||
if ($LASTEXITCODE -ne 0) { throw "Sleutelbestand aanmaken mislukt." }
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "MAAK HIER NU EEN BACK-UP VAN: $Sleutelbestand" -ForegroundColor Red
|
||||
Write-Host "Zonder dit bestand is er later geen nieuwe versie van de app meer uit te brengen." -ForegroundColor Red
|
||||
Write-Host ""
|
||||
}
|
||||
|
||||
# Het wachtwoord van het sleutelbestand. Drie wegen, in deze volgorde:
|
||||
#
|
||||
# 1. De omgevingsvariabele MIJNBESLUIT_KEYSTORE_WACHTWOORD. Zet je die als gebruikersvariabele
|
||||
# in Windows, dan kan het uitrolvenster ook een ondertekende APK bouwen. Hij staat dan wel
|
||||
# op je machine; dat is een afweging die jij maakt en niet dit script.
|
||||
# 2. Zelf intypen, als je dit script in een PowerShell-venster draait.
|
||||
# 3. Draait dit vanuit het uitrolvenster zonder die variabele, dan houdt het hier op MET een
|
||||
# melding. Dat is met opzet: zo'n venster heeft geen invoer, dus Read-Host zou daar blijven
|
||||
# wachten op iets wat nooit komt - en dan staat er een build "nog bezig" die nooit afloopt.
|
||||
if ($env:MIJNBESLUIT_KEYSTORE_WACHTWOORD) {
|
||||
$plat = $env:MIJNBESLUIT_KEYSTORE_WACHTWOORD
|
||||
}
|
||||
elseif ($env:MIJNBESLUIT_UITROLVENSTER) {
|
||||
throw @"
|
||||
Het sleutelbestand vraagt om een wachtwoord, en dit venster kan daar niet om vragen.
|
||||
|
||||
Twee manieren om verder te komen:
|
||||
* Draai dit script zelf in PowerShell: D:\MijnBesluit\tools\Apk-maken.ps1
|
||||
* Of zet het wachtwoord eenmalig in een gebruikersvariabele, dan kan het venster het ook:
|
||||
[Environment]::SetEnvironmentVariable('MIJNBESLUIT_KEYSTORE_WACHTWOORD', '<wachtwoord>', 'User')
|
||||
Daarna het uitrolvenster opnieuw starten, anders kent het die variabele nog niet.
|
||||
"@
|
||||
}
|
||||
else {
|
||||
$wachtwoord = Read-Host "Wachtwoord van het sleutelbestand" -AsSecureString
|
||||
$plat = [Runtime.InteropServices.Marshal]::PtrToStringAuto(
|
||||
[Runtime.InteropServices.Marshal]::SecureStringToBSTR($wachtwoord))
|
||||
}
|
||||
|
||||
# Leeg is geen wachtwoord. Dit is de val die een kwartier kost: in een proces zonder invoer geeft
|
||||
# Read-Host geen fout maar een lege tekst, en dan bouwt hij eerst honderd assemblies om pas bij
|
||||
# het ondertekenen om te vallen met "java.exe exited with code 2" - een melding waar niets in
|
||||
# staat over een wachtwoord. Beter hier stoppen, voordat er iets gebouwd is.
|
||||
if ([string]::IsNullOrWhiteSpace($plat)) {
|
||||
throw @"
|
||||
Er is geen wachtwoord voor het sleutelbestand opgegeven.
|
||||
|
||||
Krijg je dit terwijl je het net hebt ingetypt, dan draait dit script in een venster zonder invoer.
|
||||
Draai hem dan zelf in PowerShell, of zet het wachtwoord eenmalig in een gebruikersvariabele:
|
||||
[Environment]::SetEnvironmentVariable('MIJNBESLUIT_KEYSTORE_WACHTWOORD', '<wachtwoord>', 'User')
|
||||
"@
|
||||
}
|
||||
|
||||
$formaat = if ($Aab) { 'aab' } else { 'apk' }
|
||||
|
||||
Write-Host "$($formaat.ToUpper()) bouwen (release)..." -ForegroundColor Cyan
|
||||
dotnet publish $project -f $doel -c Release `
|
||||
-p:AndroidPackageFormat=$formaat `
|
||||
-p:AndroidKeyStore=true `
|
||||
-p:AndroidSigningKeyStore=$Sleutelbestand `
|
||||
-p:AndroidSigningKeyAlias=$Alias `
|
||||
-p:AndroidSigningStorePass=$plat `
|
||||
-p:AndroidSigningKeyPass=$plat `
|
||||
-o $Uit
|
||||
|
||||
if ($LASTEXITCODE -ne 0) { throw "Bouwen mislukt." }
|
||||
|
||||
# De ondertekende bundel heet meestal <pakketnaam>-Signed.aab, maar niet elke versie van de
|
||||
# werkbelasting hangt er "-Signed" achter. Eerst de nette naam, en anders wat er ligt.
|
||||
$pakket = Get-ChildItem $Uit -Filter "*-Signed.$formaat" | Sort-Object LastWriteTime -Descending | Select-Object -First 1
|
||||
if (-not $pakket) {
|
||||
$pakket = Get-ChildItem $Uit -Filter "*.$formaat" | Sort-Object LastWriteTime -Descending | Select-Object -First 1
|
||||
}
|
||||
if (-not $pakket) { throw "Geen ondertekende $($formaat.ToUpper()) gevonden in $Uit." }
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "Klaar: $($pakket.FullName)" -ForegroundColor Green
|
||||
|
||||
if ($Aab) {
|
||||
Write-Host ""
|
||||
Write-Host "Dit bestand gaat naar de Play Console. Op een telefoon zetten kan er niet mee;" -ForegroundColor Yellow
|
||||
Write-Host "bouw daarvoor zonder -Aab een gewone APK." -ForegroundColor Yellow
|
||||
} else {
|
||||
Write-Host "Voor de Play Store heb je geen APK nodig maar een AAB: draai dit script met -Aab."
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Publiceert MijnBesluit.Web en pakt het resultaat in als één zip-bestand.
|
||||
|
||||
.DESCRIPTION
|
||||
Draai dit op je ontwikkelmachine. Het resultaat is D:\publish\mijnbesluit.zip.
|
||||
Dat bestand pak je op de server uit met Uitrollen.ps1.
|
||||
|
||||
.EXAMPLE
|
||||
.\tools\Publiceren.ps1
|
||||
.\tools\Publiceren.ps1 -Uitvoer D:\publish -Configuratie Release
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
# Map waarin de publicatie en het zip-bestand terechtkomen.
|
||||
[string] $Uitvoer = 'D:\publish',
|
||||
|
||||
# Release voor de server, Debug alleen om iets te onderzoeken.
|
||||
[ValidateSet('Release', 'Debug')]
|
||||
[string] $Configuratie = 'Release',
|
||||
|
||||
# Sla het inpakken over als je de losse bestanden wilt hebben.
|
||||
[switch] $GeenZip
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
# De projectmap is de map boven deze scriptmap.
|
||||
$Project = Join-Path (Split-Path $PSScriptRoot -Parent) 'src\MijnBesluit.Web'
|
||||
$DoelMap = Join-Path $Uitvoer 'mijnbesluit'
|
||||
$ZipPad = Join-Path $Uitvoer 'mijnbesluit.zip'
|
||||
|
||||
if (-not (Test-Path $Project)) {
|
||||
throw "Projectmap niet gevonden: $Project. Draai dit script vanuit de map tools van het project."
|
||||
}
|
||||
|
||||
Write-Host ''
|
||||
Write-Host 'MijnBesluit publiceren' -ForegroundColor Cyan
|
||||
Write-Host " Project : $Project"
|
||||
Write-Host " Configuratie : $Configuratie"
|
||||
Write-Host " Uitvoer : $DoelMap"
|
||||
Write-Host ''
|
||||
|
||||
# Schoon beginnen: anders blijven bestanden van een vorige versie achter die nu niet meer
|
||||
# bestaan, en die worden dan mee uitgerold.
|
||||
if (Test-Path $DoelMap) {
|
||||
Write-Host 'Vorige publicatie opruimen...'
|
||||
Remove-Item $DoelMap -Recurse -Force
|
||||
}
|
||||
|
||||
Write-Host 'Publiceren...' -ForegroundColor Cyan
|
||||
dotnet publish $Project -c $Configuratie -o $DoelMap --nologo
|
||||
if ($LASTEXITCODE -ne 0) { throw 'Publiceren is mislukt. Zie de fouten hierboven.' }
|
||||
|
||||
# Controle: zonder deze twee bestanden start de site niet onder IIS.
|
||||
foreach ($nodig in @('MijnBesluit.Web.dll', 'web.config')) {
|
||||
if (-not (Test-Path (Join-Path $DoelMap $nodig))) {
|
||||
throw "Er ontbreekt iets in de publicatie: $nodig"
|
||||
}
|
||||
}
|
||||
|
||||
# appsettings.Development.json hoort niet op een server thuis.
|
||||
$ontwikkel = Join-Path $DoelMap 'appsettings.Development.json'
|
||||
if (Test-Path $ontwikkel) {
|
||||
Remove-Item $ontwikkel -Force
|
||||
Write-Host 'appsettings.Development.json verwijderd uit de publicatie.'
|
||||
}
|
||||
|
||||
if (-not $GeenZip) {
|
||||
Write-Host 'Inpakken...' -ForegroundColor Cyan
|
||||
if (Test-Path $ZipPad) { Remove-Item $ZipPad -Force }
|
||||
Compress-Archive -Path (Join-Path $DoelMap '*') -DestinationPath $ZipPad -CompressionLevel Optimal
|
||||
}
|
||||
|
||||
$grootte = if (Test-Path $ZipPad) { '{0:N1} MB' -f ((Get-Item $ZipPad).Length / 1MB) } else { '-' }
|
||||
|
||||
Write-Host ''
|
||||
Write-Host 'Klaar.' -ForegroundColor Green
|
||||
Write-Host " Map : $DoelMap"
|
||||
if (-not $GeenZip) { Write-Host " Zip : $ZipPad ($grootte)" }
|
||||
Write-Host ''
|
||||
Write-Host 'Nu op de server, in een PowerShell-venster als administrator:' -ForegroundColor Yellow
|
||||
Write-Host " .\Uitrollen.ps1 -Zip '\\tsclient\$($ZipPad.Substring(0,1))\$($ZipPad.Substring(3))'"
|
||||
Write-Host ''
|
||||
@@ -0,0 +1,3 @@
|
||||
cd D:\MijnBesluit
|
||||
.\tools\SocketServer-publiceren.ps1
|
||||
.\tools\Publiceren.ps1
|
||||
@@ -0,0 +1,214 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Controleert of de SocketServer draait, versleuteld luistert en antwoord geeft.
|
||||
|
||||
.DESCRIPTION
|
||||
Doet precies wat de app straks doet: verbinding maken, TLS opzetten, een 'ping' sturen en
|
||||
het antwoord lezen. Zo weet je dat het werkt zonder dat je eerst een APK hoeft te bouwen.
|
||||
|
||||
Het protocol: [4 bytes lengte, big-endian][UTF-8 JSON].
|
||||
|
||||
.EXAMPLE
|
||||
.\tools\SocketServer-proef.ps1
|
||||
.\tools\SocketServer-proef.ps1 -Server localhost -GeenTls
|
||||
.\tools\SocketServer-proef.ps1 -GeenTls -Email jonathan@flietstra.nl
|
||||
.\tools\SocketServer-proef.ps1 -Email iemand@example.nl -Nieuw
|
||||
.\tools\SocketServer-proef.ps1 -Acties
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[string] $Server = 'mijnbesluit.nl',
|
||||
[int] $Poort = 5200,
|
||||
|
||||
# Voor lokaal testen zonder certificaat.
|
||||
[switch] $GeenTls,
|
||||
|
||||
# Vraagt een inlogcode aan voor dit adres. Dat raakt wel de database en de mailserver,
|
||||
# en bewijst dus meer dan een ping. Er moet een account met dit adres bestaan.
|
||||
[string] $Email,
|
||||
|
||||
# Vraagt in plaats daarvan een registratiecode aan. Handig om de mailserver te toetsen met
|
||||
# een adres waar nog geen account bij hoort - bijvoorbeeld je eigen postvak. Er wordt nog
|
||||
# geen account aangemaakt; dat gebeurt pas als de code wordt ingevuld.
|
||||
[switch] $Nieuw,
|
||||
|
||||
# Vraagt of de server alle acties kent die de app gebruikt. Zo zie je of de draaiende
|
||||
# versie bij de code hoort, zonder in te loggen: een onbekende actie geeft een andere
|
||||
# melding dan een actie waarvoor je niet bent aangemeld.
|
||||
[switch] $Acties,
|
||||
|
||||
# Accepteer ook een certificaat dat niet klopt. Alleen om te onderzoeken - als dit nodig is,
|
||||
# zou de app zelf de verbinding weigeren.
|
||||
[switch] $NegeerCertificaatfouten
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
# Eén verzoek versturen en het antwoord teruglezen. Het protocol: [4 bytes lengte, big-endian]
|
||||
# gevolgd door de JSON. De lengte staat er dus vóór, zodat de ontvanger precies weet waar een
|
||||
# bericht ophoudt.
|
||||
function Stuur($stroom, $client, [string] $actie, $payload)
|
||||
{
|
||||
$verzoek = @{ requestId = [guid]::NewGuid().ToString('N'); action = $actie }
|
||||
if ($null -ne $payload) { $verzoek.payload = $payload }
|
||||
|
||||
$bytes = [System.Text.Encoding]::UTF8.GetBytes(($verzoek | ConvertTo-Json -Compress -Depth 5))
|
||||
|
||||
$lengte = [System.BitConverter]::GetBytes([int] $bytes.Length)
|
||||
if ([System.BitConverter]::IsLittleEndian) { [array]::Reverse($lengte) }
|
||||
|
||||
$stroom.Write($lengte, 0, 4)
|
||||
$stroom.Write($bytes, 0, $bytes.Length)
|
||||
$stroom.Flush()
|
||||
|
||||
$client.ReceiveTimeout = 10000
|
||||
$kop = New-Object byte[] 4
|
||||
$gelezen = 0
|
||||
while ($gelezen -lt 4) {
|
||||
$n = $stroom.Read($kop, $gelezen, 4 - $gelezen)
|
||||
if ($n -le 0) { throw "De server verbrak de verbinding zonder te antwoorden." }
|
||||
$gelezen += $n
|
||||
}
|
||||
|
||||
$kopOmgekeerd = $kop.Clone()
|
||||
if ([System.BitConverter]::IsLittleEndian) { [array]::Reverse($kopOmgekeerd) }
|
||||
$lengteAntwoord = [System.BitConverter]::ToInt32($kopOmgekeerd, 0)
|
||||
if ($lengteAntwoord -le 0 -or $lengteAntwoord -gt 16MB) { throw "Onzinnige lengte in het antwoord: $lengteAntwoord." }
|
||||
|
||||
$inhoud = New-Object byte[] $lengteAntwoord
|
||||
$gelezen = 0
|
||||
while ($gelezen -lt $lengteAntwoord) {
|
||||
$n = $stroom.Read($inhoud, $gelezen, $lengteAntwoord - $gelezen)
|
||||
if ($n -le 0) { throw "Het antwoord kwam half binnen." }
|
||||
$gelezen += $n
|
||||
}
|
||||
|
||||
return [System.Text.Encoding]::UTF8.GetString($inhoud) | ConvertFrom-Json
|
||||
}
|
||||
|
||||
Write-Host ''
|
||||
Write-Host "Proef op $Server`:$Poort" -ForegroundColor Cyan
|
||||
|
||||
$client = [System.Net.Sockets.TcpClient]::new()
|
||||
try {
|
||||
$verbinden = $client.ConnectAsync($Server, $Poort)
|
||||
if (-not $verbinden.Wait(10000)) { throw "Geen verbinding binnen 10 seconden." }
|
||||
Write-Host " Verbinding : gelukt" -ForegroundColor Green
|
||||
|
||||
$stroom = $client.GetStream()
|
||||
|
||||
if (-not $GeenTls) {
|
||||
$controle = $null
|
||||
if ($NegeerCertificaatfouten) {
|
||||
$controle = [System.Net.Security.RemoteCertificateValidationCallback] { param($a,$b,$c,$d) $true }
|
||||
}
|
||||
|
||||
$ssl = [System.Net.Security.SslStream]::new($stroom, $false, $controle)
|
||||
try {
|
||||
$ssl.AuthenticateAsClient($Server)
|
||||
} catch {
|
||||
throw "TLS mislukte: $($_.Exception.Message)`n" +
|
||||
"Luistert de server onversleuteld, probeer dan -GeenTls. Klopt het certificaat " +
|
||||
"niet bij de naam '$Server', dan is dat precies wat de app straks ook weigert."
|
||||
}
|
||||
|
||||
Write-Host " Versleuteling : $($ssl.SslProtocol)" -ForegroundColor Green
|
||||
Write-Host " Certificaat van : $($ssl.RemoteCertificate.Subject)"
|
||||
Write-Host " Geldig tot : $($ssl.RemoteCertificate.GetExpirationDateString())"
|
||||
$stroom = $ssl
|
||||
} else {
|
||||
Write-Host " Versleuteling : GEEN - hier gaan straks wachtwoorden overheen" -ForegroundColor Yellow
|
||||
}
|
||||
|
||||
# ---- acties controleren ------------------------------------------------
|
||||
if ($Acties) {
|
||||
$teControleren = @(
|
||||
'ping',
|
||||
'auth.request-code', 'auth.signin', 'auth.signout',
|
||||
'auth.request-register-code', 'auth.register', 'auth.accept-invitation',
|
||||
'account.profile', 'account.profile-save',
|
||||
'account.email-request', 'account.email-confirm',
|
||||
'account.delete-summary', 'account.delete-request', 'account.delete-confirm',
|
||||
'account.notes', 'account.notes-accept', 'account.notes-decline',
|
||||
'home.overview', 'home.lookahead',
|
||||
'family.list', 'family.members', 'family.add-member',
|
||||
'family.update-person', 'family.remove-member', 'family.invite',
|
||||
'vault.list', 'vault.open', 'vault.save', 'vault.update', 'vault.delete',
|
||||
'vault.file-begin', 'vault.file-chunk', 'vault.file-end', 'vault.file-cancel',
|
||||
'vault.file-list', 'vault.file-read', 'vault.file-delete',
|
||||
'message.inbox', 'message.outbox', 'message.read', 'message.read-sent', 'message.draft',
|
||||
'message.compose', 'message.update', 'message.withdraw', 'message.delete',
|
||||
'home.advertentie',
|
||||
'legacy.status', 'legacy.declare-death', 'legacy.object', 'legacy.appoint-manager',
|
||||
'vault.file-list-person', 'vault.file-list-message', 'vault.file-profile',
|
||||
'legacy.entrusted', 'legacy.entrusted-items', 'vault.shared-with-me',
|
||||
'legacy.managers', 'legacy.remove-manager', 'legacy.settings',
|
||||
'push.register', 'push.unregister', 'push.proef'
|
||||
)
|
||||
|
||||
$ontbreekt = @()
|
||||
foreach ($actie in $teControleren) {
|
||||
$antwoord = Stuur $stroom $client $actie $null
|
||||
# Zonder token weigert de server de meeste acties - dat is prima, het bewijst dat
|
||||
# hij ze kent. Alleen "Onbekende actie" betekent dat deze versie hem niet heeft.
|
||||
if ($antwoord.message -like '*Onbekende actie*') {
|
||||
$ontbreekt += $actie
|
||||
Write-Host (" {0,-24} ONBEKEND" -f $actie) -ForegroundColor Red
|
||||
} else {
|
||||
Write-Host (" {0,-24} bekend" -f $actie) -ForegroundColor Green
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host ''
|
||||
if ($ontbreekt.Count -eq 0) {
|
||||
Write-Host 'De server kent alle acties: de draaiende versie hoort bij deze code.' -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "De server mist $($ontbreekt.Count) actie(s). Er draait een oudere versie;" -ForegroundColor Yellow
|
||||
Write-Host 'publiceer en rol de SocketServer opnieuw uit.' -ForegroundColor Yellow
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
# ---- verzoek versturen -------------------------------------------------
|
||||
if ($Email -and $Nieuw) {
|
||||
Write-Host " Verzoek : registratiecode voor $Email"
|
||||
$antwoord = Stuur $stroom $client 'auth.request-register-code' @{
|
||||
email = $Email; firstName = 'Proef'; lastName = 'Proef'
|
||||
}
|
||||
} elseif ($Email) {
|
||||
Write-Host " Verzoek : inlogcode voor $Email"
|
||||
$antwoord = Stuur $stroom $client 'auth.request-code' @{ email = $Email }
|
||||
} else {
|
||||
$antwoord = Stuur $stroom $client 'ping' $null
|
||||
}
|
||||
|
||||
Write-Host " Antwoord : $($antwoord.status)" -ForegroundColor Green
|
||||
if ($antwoord.payload.versleuteld -ne $null) {
|
||||
Write-Host " Server zegt : verbinding versleuteld = $($antwoord.payload.versleuteld)"
|
||||
}
|
||||
Write-Host ''
|
||||
|
||||
if ($antwoord.status -eq 'Ok') {
|
||||
if ($Email) {
|
||||
Write-Host 'De SocketServer werkt, inclusief database en e-mail.' -ForegroundColor Green
|
||||
Write-Host "Er zou nu een code onderweg moeten zijn naar $Email."
|
||||
if ($Nieuw) {
|
||||
Write-Host 'Er is nog geen account aangemaakt; dat gebeurt pas als de code wordt ingevuld.'
|
||||
}
|
||||
} else {
|
||||
Write-Host 'De SocketServer werkt.' -ForegroundColor Green
|
||||
Write-Host 'Let op: een ping raakt de database niet. Draai hem nog eens met -Email om dat ook te toetsen.'
|
||||
}
|
||||
if ($GeenTls -or $antwoord.payload.versleuteld -eq $false) {
|
||||
Write-Host 'Maar zonder versleuteling. Stel Socket:CertificateThumbprint in voordat dit live gaat.' -ForegroundColor Yellow
|
||||
}
|
||||
} else {
|
||||
Write-Host "De server antwoordde met: $($antwoord.message)" -ForegroundColor Yellow
|
||||
if ($Email -and -not $Nieuw -and $antwoord.message -like '*kennen dit e-mailadres niet*') {
|
||||
Write-Host 'Draai hem met -Nieuw erbij om een registratiecode te vragen; dan hoeft er geen account te zijn.'
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
$client.Close()
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Publiceert MijnBesluit.SocketServer en pakt het in als één zip-bestand.
|
||||
|
||||
.DESCRIPTION
|
||||
Draai dit op je ontwikkelmachine. Het resultaat is D:\publish\mijnbesluit-socketserver.zip.
|
||||
Dat bestand kopieer je naar de server en pak je daar uit; installeren gaat daarna met het
|
||||
schermpje van de exe zelf (rechtermuis -> Als administrator uitvoeren -> Install).
|
||||
|
||||
Zie docs\SocketServer-installeren.md voor de stappen op de server.
|
||||
|
||||
.EXAMPLE
|
||||
.\tools\SocketServer-publiceren.ps1
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[string] $Uitvoer = 'D:\publish',
|
||||
|
||||
[ValidateSet('Release', 'Debug')]
|
||||
[string] $Configuratie = 'Release',
|
||||
|
||||
[switch] $GeenZip
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
$Project = Join-Path (Split-Path $PSScriptRoot -Parent) 'src\MijnBesluit.SocketServer'
|
||||
$DoelMap = Join-Path $Uitvoer 'mijnbesluit-socketserver'
|
||||
$ZipPad = Join-Path $Uitvoer 'mijnbesluit-socketserver.zip'
|
||||
|
||||
if (-not (Test-Path $Project)) {
|
||||
throw "Projectmap niet gevonden: $Project."
|
||||
}
|
||||
|
||||
Write-Host ''
|
||||
Write-Host 'SocketServer publiceren' -ForegroundColor Cyan
|
||||
Write-Host " Uitvoer : $DoelMap"
|
||||
Write-Host ''
|
||||
|
||||
if (Test-Path $DoelMap) {
|
||||
Write-Host 'Vorige publicatie opruimen...'
|
||||
Remove-Item $DoelMap -Recurse -Force
|
||||
}
|
||||
|
||||
# 64 bits, en niet self-contained: op de server staat .NET 8 al vanwege het Hosting Bundle.
|
||||
dotnet publish $Project -c $Configuratie -r win-x64 --self-contained false -o $DoelMap --nologo
|
||||
if ($LASTEXITCODE -ne 0) { throw 'Publiceren is mislukt. Zie de fouten hierboven.' }
|
||||
|
||||
foreach ($nodig in @('MijnBesluit.SocketServer.exe', 'appsettings.json')) {
|
||||
if (-not (Test-Path (Join-Path $DoelMap $nodig))) {
|
||||
throw "Er ontbreekt iets in de publicatie: $nodig"
|
||||
}
|
||||
}
|
||||
|
||||
# Controle die je anders pas op de server ontdekt: staat het wachtwoord er nog als voorbeeld in,
|
||||
# dan is ExtraConfigFile de plek waar het echte wachtwoord vandaan moet komen.
|
||||
$instellingen = Get-Content (Join-Path $DoelMap 'appsettings.json') -Raw | ConvertFrom-Json
|
||||
if ($instellingen.ConnectionStrings.MijnBesluit -match 'VERVANG_DIT' -and
|
||||
[string]::IsNullOrWhiteSpace($instellingen.ExtraConfigFile)) {
|
||||
throw 'Er staat geen wachtwoord in appsettings.json en ook geen ExtraConfigFile. Zo start de service niet.'
|
||||
}
|
||||
|
||||
if (-not $GeenZip) {
|
||||
if (Test-Path $ZipPad) { Remove-Item $ZipPad -Force }
|
||||
Compress-Archive -Path (Join-Path $DoelMap '*') -DestinationPath $ZipPad
|
||||
Write-Host ''
|
||||
Write-Host "Klaar: $ZipPad" -ForegroundColor Green
|
||||
Write-Host 'Kopieer dit naar de server, pak het uit, en start de exe als administrator.'
|
||||
} else {
|
||||
Write-Host ''
|
||||
Write-Host "Klaar: $DoelMap" -ForegroundColor Green
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Zet een nieuwe versie van de SocketServer op deze server.
|
||||
|
||||
.DESCRIPTION
|
||||
Draai dit OP DE SERVER, in een PowerShell dat je als administrator hebt geopend.
|
||||
|
||||
Het script stopt de service, bewaart de huidige versie én je appsettings.json, pakt de
|
||||
nieuwe versie uit, zet de instellingen terug en start de service weer. Start hij niet,
|
||||
dan wordt de vorige versie teruggezet.
|
||||
|
||||
Je instellingen blijven dus staan - ook de vingerafdruk van het certificaat.
|
||||
|
||||
.EXAMPLE
|
||||
C:\beheer\SocketServer-uitrollen.ps1 -Zip \\tsclient\D\publish\mijnbesluit-socketserver.zip
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string] $Zip,
|
||||
|
||||
[string] $Doel = 'C:\MijnBesluitSocket',
|
||||
[string] $Service = 'MijnBesluitSocket',
|
||||
[int] $BewaarVersies = 5
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
$beheerder = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()
|
||||
).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
|
||||
if (-not $beheerder) {
|
||||
throw 'Dit script heeft beheerdersrechten nodig. Open PowerShell met "Als administrator uitvoeren".'
|
||||
}
|
||||
|
||||
if (-not (Test-Path $Zip)) { throw "Het zip-bestand is niet gevonden: $Zip" }
|
||||
if (-not (Test-Path $Doel)) { throw "De map $Doel bestaat niet. Is de SocketServer hier wel geinstalleerd?" }
|
||||
|
||||
$Stempel = Get-Date -Format 'yyyyMMdd-HHmmss'
|
||||
$Instelling = Join-Path $Doel 'appsettings.json'
|
||||
$Bewaarmap = Join-Path (Split-Path $Doel -Parent) '_vorige-socketserver'
|
||||
|
||||
Write-Host ''
|
||||
Write-Host 'SocketServer uitrollen' -ForegroundColor Cyan
|
||||
Write-Host " Zip : $Zip"
|
||||
Write-Host " Doel : $Doel"
|
||||
Write-Host " Service : $Service"
|
||||
Write-Host ''
|
||||
|
||||
# Eerst uitpakken naar een tijdelijke map, zodat de service maar kort uit staat.
|
||||
$Tijdelijk = Join-Path $env:TEMP "mijnbesluit-socket-$Stempel"
|
||||
Write-Host 'Uitpakken...' -ForegroundColor Cyan
|
||||
Expand-Archive -Path $Zip -DestinationPath $Tijdelijk -Force
|
||||
|
||||
if (-not (Test-Path (Join-Path $Tijdelijk 'MijnBesluit.SocketServer.exe'))) {
|
||||
Remove-Item $Tijdelijk -Recurse -Force
|
||||
throw 'Dit lijkt geen geldige publicatie: MijnBesluit.SocketServer.exe ontbreekt in het zip-bestand.'
|
||||
}
|
||||
|
||||
# De instellingen zijn van jou, niet van de publicatie: die gaan er straks weer overheen.
|
||||
$instellingenBewaard = $null
|
||||
if (Test-Path $Instelling) {
|
||||
$instellingenBewaard = Join-Path $env:TEMP "appsettings-$Stempel.json"
|
||||
Copy-Item $Instelling $instellingenBewaard -Force
|
||||
Write-Host 'Instellingen bewaard.'
|
||||
}
|
||||
|
||||
$draaide = (Get-Service $Service -ErrorAction SilentlyContinue).Status -eq 'Running'
|
||||
if ($draaide) {
|
||||
Write-Host 'Service stoppen...' -ForegroundColor Cyan
|
||||
Stop-Service $Service
|
||||
# Windows geeft de bestanden niet altijd meteen vrij.
|
||||
Start-Sleep -Seconds 2
|
||||
}
|
||||
|
||||
New-Item -ItemType Directory -Path $Bewaarmap -Force | Out-Null
|
||||
$vorige = Join-Path $Bewaarmap "socketserver-$Stempel"
|
||||
Write-Host 'Vorige versie bewaren...' -ForegroundColor Cyan
|
||||
Copy-Item $Doel $vorige -Recurse -Force
|
||||
|
||||
try {
|
||||
Write-Host 'Nieuwe versie plaatsen...' -ForegroundColor Cyan
|
||||
Copy-Item (Join-Path $Tijdelijk '*') $Doel -Recurse -Force
|
||||
|
||||
if ($instellingenBewaard) {
|
||||
Copy-Item $instellingenBewaard $Instelling -Force
|
||||
Write-Host 'Instellingen teruggezet.'
|
||||
}
|
||||
|
||||
Write-Host 'Service starten...' -ForegroundColor Cyan
|
||||
Start-Service $Service
|
||||
Start-Sleep -Seconds 3
|
||||
|
||||
$stand = (Get-Service $Service).Status
|
||||
if ($stand -ne 'Running') { throw "De service staat op '$stand' in plaats van 'Running'." }
|
||||
}
|
||||
catch {
|
||||
Write-Host ''
|
||||
Write-Host "Mislukt: $($_.Exception.Message)" -ForegroundColor Red
|
||||
Write-Host 'Vorige versie terugzetten...' -ForegroundColor Yellow
|
||||
|
||||
Stop-Service $Service -ErrorAction SilentlyContinue
|
||||
Start-Sleep -Seconds 2
|
||||
Copy-Item (Join-Path $vorige '*') $Doel -Recurse -Force
|
||||
Start-Service $Service -ErrorAction SilentlyContinue
|
||||
|
||||
throw 'De nieuwe versie is teruggedraaid. Kijk in Logboeken > Windows-logboeken > Toepassing.'
|
||||
}
|
||||
finally {
|
||||
Remove-Item $Tijdelijk -Recurse -Force -ErrorAction SilentlyContinue
|
||||
if ($instellingenBewaard) { Remove-Item $instellingenBewaard -Force -ErrorAction SilentlyContinue }
|
||||
}
|
||||
|
||||
# Oude versies opruimen, anders loopt de schijf vol.
|
||||
Get-ChildItem $Bewaarmap -Directory | Sort-Object Name -Descending |
|
||||
Select-Object -Skip $BewaarVersies | Remove-Item -Recurse -Force
|
||||
|
||||
Write-Host ''
|
||||
Write-Host 'Klaar. De service draait.' -ForegroundColor Green
|
||||
Write-Host " Vorige versie staat in: $vorige"
|
||||
Write-Host ''
|
||||
Write-Host 'Controleer vanaf je eigen pc met:'
|
||||
Write-Host ' D:\MijnBesluit\tools\SocketServer-proef.ps1'
|
||||
@@ -0,0 +1,225 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Rolt een gepubliceerde versie van MijnBesluit uit op deze server.
|
||||
|
||||
.DESCRIPTION
|
||||
Draai dit OP DE SERVER, in een PowerShell-venster dat je als administrator hebt geopend.
|
||||
|
||||
Het script haalt het pad en de toepassingsgroep uit IIS, zet de site stil, bewaart de huidige
|
||||
versie als terugvaloptie, pakt de nieuwe versie uit, start de site en controleert of hij
|
||||
antwoordt. Gaat er iets mis, dan wordt de vorige versie teruggezet.
|
||||
|
||||
De map met gegevens (sleutelbestand, kluisbestanden, appsettings.secrets.json) wordt niet
|
||||
aangeraakt: die staat daar bewust buiten.
|
||||
|
||||
.EXAMPLE
|
||||
# De zip rechtstreeks van je eigen pc halen via de externe-bureaubladverbinding:
|
||||
.\Uitrollen.ps1 -Zip \\tsclient\D\publish\mijnbesluit.zip
|
||||
|
||||
.EXAMPLE
|
||||
# Of vanaf een bestand dat al op de server staat:
|
||||
.\Uitrollen.ps1 -Zip D:\mijnbesluit.zip
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
# Het zip-bestand dat Publiceren.ps1 heeft gemaakt.
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string] $Zip,
|
||||
|
||||
# De naam van de site zoals die in IIS staat. Pad en toepassingsgroep worden daaruit
|
||||
# opgehaald, zodat je die niet hoeft te onthouden.
|
||||
[string] $Site = 'mijnbesluit',
|
||||
|
||||
# Alleen invullen als je wilt afwijken van wat er in IIS staat.
|
||||
[string] $Doel,
|
||||
[string] $Pool,
|
||||
|
||||
# Adres om na afloop te controleren. Niet meegeven laat het script het afleiden uit de
|
||||
# bindingen van de site; een lege tekst slaat de controle over.
|
||||
[string] $Controleer,
|
||||
|
||||
# Zoveel vorige versies blijven bewaard om op terug te kunnen vallen.
|
||||
[int] $BewaarVersies = 5
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
# ---------------------------------------------------------------- vooraf controleren
|
||||
|
||||
$beheerder = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()
|
||||
).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
|
||||
if (-not $beheerder) {
|
||||
throw 'Dit script heeft beheerdersrechten nodig. Open PowerShell met "Als administrator uitvoeren".'
|
||||
}
|
||||
|
||||
if (-not (Test-Path $Zip)) {
|
||||
throw "Het zip-bestand is niet gevonden: $Zip"
|
||||
}
|
||||
|
||||
Import-Module WebAdministration -ErrorAction Stop
|
||||
|
||||
# ---------------------------------------------------------------- gegevens uit IIS halen
|
||||
|
||||
$website = Get-Website -Name $Site -ErrorAction SilentlyContinue
|
||||
if (-not $website) {
|
||||
$bestaande = (Get-Website | Select-Object -ExpandProperty Name) -join ', '
|
||||
throw "Site '$Site' bestaat niet in IIS. Aanwezige sites: $bestaande"
|
||||
}
|
||||
|
||||
if (-not $Doel) { $Doel = [Environment]::ExpandEnvironmentVariables($website.physicalPath) }
|
||||
if (-not $Pool) { $Pool = $website.applicationPool }
|
||||
|
||||
if (-not (Test-Path "IIS:\AppPools\$Pool")) {
|
||||
throw "De toepassingsgroep '$Pool' bestaat niet in IIS."
|
||||
}
|
||||
|
||||
# Een ASP.NET Core-applicatie hoort in een toepassingsgroep zonder beheerde code te draaien.
|
||||
# Staat dat verkeerd, dan krijg je een 500.19 of 500.21 die lastig te herleiden is.
|
||||
$runtime = (Get-ItemProperty "IIS:\AppPools\$Pool" -Name managedRuntimeVersion).Value
|
||||
if ($runtime -ne '') {
|
||||
Write-Host ''
|
||||
Write-Host "Let op: toepassingsgroep '$Pool' staat op .NET CLR-versie '$runtime'." -ForegroundColor Yellow
|
||||
Write-Host 'Voor ASP.NET Core hoort dat "Geen beheerde code" te zijn. Aanpassen met:' -ForegroundColor Yellow
|
||||
Write-Host " Set-ItemProperty 'IIS:\AppPools\$Pool' -Name managedRuntimeVersion -Value ''"
|
||||
Write-Host ''
|
||||
}
|
||||
|
||||
# Controleadres afleiden uit de bindingen als het niet is meegegeven.
|
||||
if (-not $PSBoundParameters.ContainsKey('Controleer')) {
|
||||
$binding = $website.bindings.Collection | Where-Object { $_.protocol -eq 'https' } | Select-Object -First 1
|
||||
if (-not $binding) { $binding = $website.bindings.Collection | Select-Object -First 1 }
|
||||
|
||||
if ($binding) {
|
||||
# bindingInformation ziet eruit als "*:443:mijnbesluit.nl"
|
||||
$delen = $binding.bindingInformation -split ':'
|
||||
$hostnaam = if ($delen.Count -ge 3 -and $delen[2]) { $delen[2] } else { 'localhost' }
|
||||
$Controleer = "$($binding.protocol)://$hostnaam/inloggen"
|
||||
}
|
||||
}
|
||||
|
||||
$BackupWortel = Join-Path (Split-Path $Doel -Parent) '_vorige-versies'
|
||||
$Stempel = Get-Date -Format 'yyyyMMdd-HHmmss'
|
||||
$BackupMap = Join-Path $BackupWortel "$(Split-Path $Doel -Leaf)-$Stempel"
|
||||
|
||||
Write-Host ''
|
||||
Write-Host 'MijnBesluit uitrollen' -ForegroundColor Cyan
|
||||
Write-Host " Zip : $Zip"
|
||||
Write-Host " Site : $Site"
|
||||
Write-Host " Doel : $Doel"
|
||||
Write-Host " App-pool : $Pool"
|
||||
Write-Host " Controleer : $(if ($Controleer) { $Controleer } else { '(overslaan)' })"
|
||||
Write-Host ''
|
||||
|
||||
# ---------------------------------------------------------------- uitpakken naar een tijdelijke map
|
||||
|
||||
# Eerst helemaal uitpakken en controleren, en pas daarna de site stilzetten. Zo staat de site
|
||||
# maar een paar seconden uit, en niet de hele tijd dat het uitpakken duurt.
|
||||
$Tijdelijk = Join-Path $env:TEMP "mijnbesluit-$Stempel"
|
||||
Write-Host 'Uitpakken...' -ForegroundColor Cyan
|
||||
Expand-Archive -Path $Zip -DestinationPath $Tijdelijk -Force
|
||||
|
||||
foreach ($nodig in @('MijnBesluit.Web.dll', 'web.config')) {
|
||||
if (-not (Test-Path (Join-Path $Tijdelijk $nodig))) {
|
||||
Remove-Item $Tijdelijk -Recurse -Force
|
||||
throw "Dit lijkt geen geldige publicatie: $nodig ontbreekt in het zip-bestand."
|
||||
}
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------- site stilzetten
|
||||
|
||||
$draaide = (Get-WebAppPoolState -Name $Pool).Value -eq 'Started'
|
||||
if ($draaide) {
|
||||
Write-Host 'Toepassingsgroep stoppen...' -ForegroundColor Cyan
|
||||
Stop-WebAppPool -Name $Pool
|
||||
|
||||
# Wachten tot IIS de bestanden echt heeft losgelaten; anders mislukt het kopieren.
|
||||
$wachtTot = (Get-Date).AddSeconds(30)
|
||||
while ((Get-WebAppPoolState -Name $Pool).Value -ne 'Stopped' -and (Get-Date) -lt $wachtTot) {
|
||||
Start-Sleep -Milliseconds 500
|
||||
}
|
||||
Start-Sleep -Seconds 2
|
||||
}
|
||||
|
||||
try {
|
||||
# ------------------------------------------------------------ vorige versie bewaren
|
||||
|
||||
if (Test-Path $Doel) {
|
||||
Write-Host 'Vorige versie bewaren...' -ForegroundColor Cyan
|
||||
New-Item -ItemType Directory -Path $BackupWortel -Force | Out-Null
|
||||
Move-Item -Path $Doel -Destination $BackupMap -Force
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------ nieuwe versie neerzetten
|
||||
|
||||
Write-Host 'Nieuwe versie plaatsen...' -ForegroundColor Cyan
|
||||
New-Item -ItemType Directory -Path $Doel -Force | Out-Null
|
||||
Copy-Item -Path (Join-Path $Tijdelijk '*') -Destination $Doel -Recurse -Force
|
||||
}
|
||||
catch {
|
||||
Write-Host 'Er ging iets mis; vorige versie terugzetten...' -ForegroundColor Red
|
||||
if ((Test-Path $BackupMap) -and -not (Test-Path (Join-Path $Doel 'MijnBesluit.Web.dll'))) {
|
||||
if (Test-Path $Doel) { Remove-Item $Doel -Recurse -Force }
|
||||
Move-Item -Path $BackupMap -Destination $Doel -Force
|
||||
}
|
||||
if ($draaide) { Start-WebAppPool -Name $Pool }
|
||||
throw
|
||||
}
|
||||
finally {
|
||||
if (Test-Path $Tijdelijk) { Remove-Item $Tijdelijk -Recurse -Force }
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------- weer starten
|
||||
|
||||
Write-Host 'Toepassingsgroep starten...' -ForegroundColor Cyan
|
||||
Start-WebAppPool -Name $Pool
|
||||
|
||||
# ---------------------------------------------------------------- controleren
|
||||
|
||||
if ($Controleer) {
|
||||
Write-Host "Controleren: $Controleer" -ForegroundColor Cyan
|
||||
$gelukt = $false
|
||||
|
||||
# De eerste aanroep duurt langer: dan start de applicatie op.
|
||||
for ($poging = 1; $poging -le 10; $poging++) {
|
||||
try {
|
||||
$antwoord = Invoke-WebRequest -Uri $Controleer -UseBasicParsing -TimeoutSec 30
|
||||
if ($antwoord.StatusCode -eq 200) { $gelukt = $true; break }
|
||||
}
|
||||
catch {
|
||||
Start-Sleep -Seconds 3
|
||||
}
|
||||
}
|
||||
|
||||
if ($gelukt) {
|
||||
Write-Host 'De site antwoordt.' -ForegroundColor Green
|
||||
}
|
||||
else {
|
||||
Write-Host ''
|
||||
Write-Host 'De site antwoordt niet.' -ForegroundColor Red
|
||||
Write-Host 'Kijk in Logboeken > Windows-logboeken > Toepassing, of zet in web.config'
|
||||
Write-Host 'stdoutLogEnabled op true en kijk daarna in de map logs.'
|
||||
Write-Host ''
|
||||
Write-Host 'Terugvallen op de vorige versie:' -ForegroundColor Yellow
|
||||
Write-Host " Stop-WebAppPool '$Pool'"
|
||||
Write-Host " Remove-Item '$Doel' -Recurse -Force"
|
||||
Write-Host " Move-Item '$BackupMap' '$Doel'"
|
||||
Write-Host " Start-WebAppPool '$Pool'"
|
||||
}
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------- oude versies opruimen
|
||||
|
||||
if (Test-Path $BackupWortel) {
|
||||
Get-ChildItem $BackupWortel -Directory |
|
||||
Sort-Object Name -Descending |
|
||||
Select-Object -Skip $BewaarVersies |
|
||||
ForEach-Object {
|
||||
Write-Host "Oude versie opruimen: $($_.Name)"
|
||||
Remove-Item $_.FullName -Recurse -Force
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host ''
|
||||
Write-Host 'Klaar.' -ForegroundColor Green
|
||||
Write-Host " Vorige versie staat in: $BackupMap"
|
||||
Write-Host ''
|
||||
@@ -0,0 +1,60 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Publiceert MijnBesluit.Uitroller (het venster op je eigen pc) naar D:\MijnBesluitTools\pc,
|
||||
met behoud van je eigen instellingen en geheimen.
|
||||
|
||||
.DESCRIPTION
|
||||
D:\publish is van de uitrolPAKKETTEN (de zip's voor site/socketserver/apk) en blijft daarvoor
|
||||
gereserveerd. De uitroller zelf krijgt, net als RenH.Uitroller met D:\RenHTools, zijn eigen map:
|
||||
|
||||
D:\MijnBesluitTools\pc\ - de exe en alles wat dotnet publish neerzet
|
||||
D:\MijnBesluitTools\uitroller.json - server, geheim, projectmap, testadres, enz.
|
||||
D:\MijnBesluitTools\uitroller.secrets.json - het Gitea-token (los bestand, buiten git)
|
||||
|
||||
De twee bestanden hierboven staan een map BOVEN de exe, dus een publish (die alleen de
|
||||
pc-submap ververst) kan ze niet wissen - dat is precies waarom Instellingen.cs en
|
||||
Uitrollergeheimen.cs ze daar zoeken (net als RenH.Uitroller bij D:\RenHTools).
|
||||
|
||||
.EXAMPLE
|
||||
cd D:\MijnBesluit
|
||||
.\tools\Uitroller-publiceren.ps1
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[string] $Doel = 'D:\MijnBesluitTools'
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
$Projectmap = Split-Path $PSScriptRoot -Parent
|
||||
$Pcmap = Join-Path $Doel 'pc'
|
||||
|
||||
New-Item -ItemType Directory -Force -Path $Doel | Out-Null
|
||||
New-Item -ItemType Directory -Force -Path $Pcmap | Out-Null
|
||||
|
||||
Write-Host ''
|
||||
Write-Host "MijnBesluit.Uitroller -> $Pcmap" -ForegroundColor Cyan
|
||||
dotnet publish (Join-Path $Projectmap 'src\MijnBesluit.Uitroller') -c Release -o $Pcmap --nologo
|
||||
if ($LASTEXITCODE -ne 0) { throw 'Publiceren van MijnBesluit.Uitroller is mislukt.' }
|
||||
|
||||
# uitroller.json en uitroller.secrets.json staan in $Doel zelf (een map boven de exe) en worden
|
||||
# door dotnet publish dus niet aangeraakt - alleen $Pcmap wordt ververst. Bestaat
|
||||
# uitroller.secrets.json daar nog nergens (eerste keer publiceren), dan hier een lege maar
|
||||
# geldige versie neerzetten, anders moet je 'm de eerste keer met de hand aanmaken voordat de
|
||||
# Gitea-knoppen iets kunnen.
|
||||
$geheimenPad = Join-Path $Doel 'uitroller.secrets.json'
|
||||
if (-not (Test-Path $geheimenPad)) {
|
||||
Set-Content -Path $geheimenPad -Value "{`n `"Gitea`": { `"Token`": `"`" }`n}`n" -NoNewline -Encoding UTF8
|
||||
Write-Host " uitroller.secrets.json aangemaakt (leeg) - vul je Gitea-token in op:" -ForegroundColor Yellow
|
||||
Write-Host " $geheimenPad" -ForegroundColor Yellow
|
||||
}
|
||||
|
||||
$instellingenPad = Join-Path $Doel 'uitroller.json'
|
||||
if (-not (Test-Path $instellingenPad)) {
|
||||
Write-Host " Let op: er staat nog geen uitroller.json in $Doel." -ForegroundColor Yellow
|
||||
Write-Host " Bij de eerste start kopieert het venster 'm zelf over vanuit $Pcmap." -ForegroundColor Yellow
|
||||
}
|
||||
|
||||
Write-Host ''
|
||||
Write-Host 'Klaar.' -ForegroundColor Green
|
||||
Write-Host " $Pcmap\MijnBesluit.Uitroller.exe"
|
||||
Write-Host ''
|
||||
Reference in New Issue
Block a user