78 lines
5.0 KiB
PowerShell
78 lines
5.0 KiB
PowerShell
param([Parameter(Mandatory)][string]$BridgeArchive,[Parameter(Mandatory)][string]$FullArchive)
|
|
$ErrorActionPreference='Stop'
|
|
Add-Type @'
|
|
using System;
|
|
using System.Runtime.InteropServices;
|
|
public static class UpdateResource {
|
|
[DllImport("kernel32.dll", CharSet=CharSet.Unicode)] static extern IntPtr LoadLibraryEx(string path, IntPtr file, uint flags);
|
|
[DllImport("kernel32.dll")] static extern IntPtr FindResource(IntPtr module, IntPtr name, IntPtr type);
|
|
[DllImport("kernel32.dll")] static extern IntPtr LoadResource(IntPtr module, IntPtr resource);
|
|
[DllImport("kernel32.dll")] static extern IntPtr LockResource(IntPtr resource);
|
|
[DllImport("kernel32.dll")] static extern uint SizeofResource(IntPtr module, IntPtr resource);
|
|
[DllImport("kernel32.dll")] static extern bool FreeLibrary(IntPtr module);
|
|
public static byte[] Read(string path) {
|
|
var module=LoadLibraryEx(path,IntPtr.Zero,2|32);
|
|
if(module==IntPtr.Zero) throw new Exception("Cannot load bridge resources");
|
|
try {
|
|
var resource=FindResource(module,(IntPtr)201,(IntPtr)10);
|
|
var size=SizeofResource(module,resource);
|
|
if(size==0 || size>1024*1024) throw new Exception("Invalid bridge updater resource");
|
|
var bytes=new byte[size];
|
|
Marshal.Copy(LockResource(LoadResource(module,resource)),bytes,0,(int)size);
|
|
return bytes;
|
|
} finally { FreeLibrary(module); }
|
|
}
|
|
}
|
|
'@
|
|
$root=Join-Path ([IO.Path]::GetTempPath()) ('KSwitcher-transition-'+[guid]::NewGuid().ToString('N'))
|
|
[IO.Directory]::CreateDirectory($root) | Out-Null
|
|
try {
|
|
$legacy=Join-Path $root 'legacy.ps1'
|
|
$oldSource=git -C (Join-Path $PSScriptRoot '..') show v0.4.1:resources/update.ps1
|
|
if ($LASTEXITCODE) { throw 'Cannot read the released v0.4.1 updater.' }
|
|
$oldSource | Set-Content -LiteralPath $legacy -Encoding utf8
|
|
$releases=@('v0.4.2','release-v0.5.0') | ForEach-Object {
|
|
@{tag_name=$_;draft=$false;prerelease=$false;assets=@(
|
|
@{name='KSwitcher-win-x64.zip';browser_download_url="https://gitea.hrynco.com/hrynco/hrynco-kswitcher/releases/download/$_/KSwitcher-win-x64.zip"},
|
|
@{name='SHA256SUMS.txt';browser_download_url="https://gitea.hrynco.com/hrynco/hrynco-kswitcher/releases/download/$_/SHA256SUMS.txt"})}
|
|
}
|
|
$install=Join-Path $root 'install'
|
|
[IO.Directory]::CreateDirectory((Join-Path $install 'data')) | Out-Null
|
|
[IO.Directory]::CreateDirectory((Join-Path $install 'dictionaries')) | Out-Null
|
|
[IO.File]::WriteAllText((Join-Path $install 'data/settings.json'),'personal settings')
|
|
[IO.File]::WriteAllText((Join-Path $install 'dictionaries/en.txt'),'personal dictionary')
|
|
& {
|
|
. $legacy -Library
|
|
$selected=Select-Release $releases ([version]'0.4.1')
|
|
if ($selected.version -ne 'v0.4.2') { throw 'Legacy client skipped the bridge.' }
|
|
$stage=Join-Path $root 'bridge-stage'
|
|
Expand-Release $BridgeArchive $stage ([version]'0.4.2')
|
|
$changed=[Collections.Generic.List[string]]::new()
|
|
Install-Files $stage $install (Join-Path $root 'bridge-backup') $changed
|
|
}
|
|
$bridgeHelper=Join-Path $root 'bridge-helper.ps1'
|
|
[IO.File]::WriteAllBytes($bridgeHelper,[UpdateResource]::Read((Join-Path $install 'KSwitcher.exe')))
|
|
. $bridgeHelper -Library
|
|
$selected=Select-Release $releases ([version]'0.4.2')
|
|
if ($selected.version -ne 'release-v0.5.0') { throw 'Bridge did not find the full release.' }
|
|
$stage=Join-Path $root 'full-stage'
|
|
Expand-Release $FullArchive $stage ([version]'0.5.0')
|
|
$changed=[Collections.Generic.List[string]]::new()
|
|
Install-Files $stage $install (Join-Path $root 'full-backup') $changed
|
|
foreach ($name in @('KSwitcher.exe','KSwitcher.Config.exe','KSwitcher.Screenshot.exe')) {
|
|
$version=[Diagnostics.FileVersionInfo]::GetVersionInfo((Join-Path $install $name)).FileVersion
|
|
if ((Get-StableVersion $version) -ne [version]'0.5.0') { throw "Incorrect installed version: $name" }
|
|
}
|
|
if ([IO.File]::ReadAllText((Join-Path $install 'data/settings.json')) -ne 'personal settings' -or
|
|
[IO.File]::ReadAllText((Join-Path $install 'dictionaries/en.txt')) -ne 'personal dictionary') { throw 'User data changed during transition.' }
|
|
if (Select-Release $releases ([version]'0.5.0')) { throw 'Current version offers another update.' }
|
|
Undo-Files $install (Join-Path $root 'full-backup') $changed
|
|
if ((Get-StableVersion ([Diagnostics.FileVersionInfo]::GetVersionInfo((Join-Path $install 'KSwitcher.exe')).FileVersion)) -ne [version]'0.4.2' -or
|
|
(Test-Path -LiteralPath (Join-Path $install 'KSwitcher.Screenshot.exe'))) { throw 'Full release rollback did not restore the bridge.' }
|
|
'Passed real-package transition: v0.4.1 updater -> v0.4.2 bridge -> release-v0.5.0; user data preserved; rollback verified.'
|
|
} finally {
|
|
if ([IO.Path]::GetDirectoryName($root) -eq [IO.Path]::GetTempPath().TrimEnd('\') -and (Split-Path -Leaf $root) -like 'KSwitcher-transition-*') {
|
|
Remove-Item -LiteralPath $root -Recurse -Force
|
|
}
|
|
}
|