mirror of
https://github.com/ZoiteChat/zoitechat.git
synced 2026-10-15 01:57:12 +00:00
msi/msix support
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Package
|
||||
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
|
||||
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
|
||||
xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3"
|
||||
xmlns:uap10="http://schemas.microsoft.com/appx/manifest/uap/windows10/10"
|
||||
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
|
||||
IgnorableNamespaces="uap uap3 uap10 rescap">
|
||||
|
||||
<!--
|
||||
Identity values are filled by build-msix.ps1. For Microsoft Store
|
||||
submissions they must exactly match Product management > Product identity
|
||||
in Partner Center.
|
||||
-->
|
||||
<Identity
|
||||
Name="@IDENTITY_NAME@"
|
||||
Publisher="@PUBLISHER@"
|
||||
Version="@PACKAGE_VERSION@"
|
||||
ProcessorArchitecture="x64" />
|
||||
|
||||
<Properties>
|
||||
<DisplayName>ZoiteChat</DisplayName>
|
||||
<PublisherDisplayName>@PUBLISHER_DISPLAY_NAME@</PublisherDisplayName>
|
||||
<Description>ZoiteChat IRC client</Description>
|
||||
<Logo>Assets\StoreLogo.png</Logo>
|
||||
</Properties>
|
||||
|
||||
<Resources>
|
||||
<Resource Language="en-us" />
|
||||
</Resources>
|
||||
|
||||
<Dependencies>
|
||||
<TargetDeviceFamily
|
||||
Name="Windows.Desktop"
|
||||
MinVersion="10.0.19041.0"
|
||||
MaxVersionTested="10.0.26100.0" />
|
||||
<PackageDependency
|
||||
Name="Microsoft.VCLibs.140.00.UWPDesktop"
|
||||
Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US"
|
||||
MinVersion="14.0.30704.0" />
|
||||
</Dependencies>
|
||||
|
||||
<Capabilities>
|
||||
<rescap:Capability Name="runFullTrust" />
|
||||
</Capabilities>
|
||||
|
||||
<Applications>
|
||||
<Application
|
||||
Id="ZoiteChat"
|
||||
Executable="ZoiteChat\zoitechat.exe"
|
||||
uap10:RuntimeBehavior="packagedClassicApp"
|
||||
uap10:TrustLevel="mediumIL">
|
||||
|
||||
<uap:VisualElements
|
||||
DisplayName="ZoiteChat"
|
||||
Description="ZoiteChat IRC client"
|
||||
BackgroundColor="transparent"
|
||||
Square150x150Logo="Assets\Square150x150Logo.png"
|
||||
Square44x44Logo="Assets\Square44x44Logo.png" />
|
||||
|
||||
<Extensions>
|
||||
<uap3:Extension Category="windows.protocol">
|
||||
<uap3:Protocol
|
||||
Name="irc"
|
||||
Parameters="--url="%1"" />
|
||||
</uap3:Extension>
|
||||
|
||||
<uap3:Extension Category="windows.fileTypeAssociation">
|
||||
<uap3:FileTypeAssociation
|
||||
Name="zoitechattheme"
|
||||
Parameters=""%1"">
|
||||
<uap:DisplayName>ZoiteChat Theme</uap:DisplayName>
|
||||
<uap:SupportedFileTypes>
|
||||
<uap:FileType>.zct</uap:FileType>
|
||||
<uap:FileType>.hct</uap:FileType>
|
||||
</uap:SupportedFileTypes>
|
||||
</uap3:FileTypeAssociation>
|
||||
</uap3:Extension>
|
||||
</Extensions>
|
||||
</Application>
|
||||
</Applications>
|
||||
</Package>
|
||||
@@ -0,0 +1,392 @@
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string] $SourceDir,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string] $OutputPath,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[ValidatePattern('^\d+\.\d+\.\d+\.0$')]
|
||||
[string] $PackageVersion,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string] $IdentityName,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string] $Publisher,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string] $PublisherDisplayName,
|
||||
|
||||
[switch] $SelfSign
|
||||
)
|
||||
|
||||
Set-StrictMode -Version Latest
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
Add-Type -AssemblyName System.Drawing
|
||||
|
||||
function Find-WindowsSdkTool {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string] $ToolName
|
||||
)
|
||||
|
||||
$command = Get-Command $ToolName -ErrorAction SilentlyContinue
|
||||
if ($command) {
|
||||
return $command.Source
|
||||
}
|
||||
|
||||
$kitsRoot = Join-Path ${env:ProgramFiles(x86)} 'Windows Kits\10\bin'
|
||||
if (-not (Test-Path $kitsRoot)) {
|
||||
throw "Windows SDK bin directory was not found: $kitsRoot"
|
||||
}
|
||||
|
||||
$tool = Get-ChildItem -Path $kitsRoot -Filter $ToolName -File -Recurse |
|
||||
Where-Object { $_.FullName -match '\\x64\\' } |
|
||||
Sort-Object {
|
||||
$versionDirectory = Split-Path (Split-Path $_.DirectoryName -Parent) -Leaf
|
||||
try {
|
||||
[version] $versionDirectory
|
||||
}
|
||||
catch {
|
||||
[version] '0.0'
|
||||
}
|
||||
} -Descending |
|
||||
Select-Object -First 1
|
||||
|
||||
if (-not $tool) {
|
||||
throw "$ToolName was not found in the installed Windows SDK."
|
||||
}
|
||||
|
||||
return $tool.FullName
|
||||
}
|
||||
|
||||
function Escape-Xml {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string] $Value
|
||||
)
|
||||
|
||||
return [System.Security.SecurityElement]::Escape($Value)
|
||||
}
|
||||
|
||||
function New-MsixAsset {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[System.Drawing.Image] $SourceImage,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[int] $Width,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[int] $Height,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string] $Path
|
||||
)
|
||||
|
||||
$bitmap = [System.Drawing.Bitmap]::new($Width, $Height)
|
||||
try {
|
||||
$graphics = [System.Drawing.Graphics]::FromImage($bitmap)
|
||||
try {
|
||||
$graphics.Clear([System.Drawing.Color]::Transparent)
|
||||
$graphics.InterpolationMode = [System.Drawing.Drawing2D.InterpolationMode]::HighQualityBicubic
|
||||
$graphics.PixelOffsetMode = [System.Drawing.Drawing2D.PixelOffsetMode]::HighQuality
|
||||
$graphics.SmoothingMode = [System.Drawing.Drawing2D.SmoothingMode]::HighQuality
|
||||
|
||||
$scale = [Math]::Min($Width / $SourceImage.Width, $Height / $SourceImage.Height)
|
||||
$drawWidth = [Math]::Max(1, [int][Math]::Round($SourceImage.Width * $scale))
|
||||
$drawHeight = [Math]::Max(1, [int][Math]::Round($SourceImage.Height * $scale))
|
||||
$x = [int](($Width - $drawWidth) / 2)
|
||||
$y = [int](($Height - $drawHeight) / 2)
|
||||
|
||||
$graphics.DrawImage($SourceImage, $x, $y, $drawWidth, $drawHeight)
|
||||
}
|
||||
finally {
|
||||
$graphics.Dispose()
|
||||
}
|
||||
|
||||
$bitmap.Save($Path, [System.Drawing.Imaging.ImageFormat]::Png)
|
||||
}
|
||||
finally {
|
||||
$bitmap.Dispose()
|
||||
}
|
||||
}
|
||||
|
||||
$source = (Resolve-Path $SourceDir).Path
|
||||
if (-not (Test-Path (Join-Path $source 'zoitechat.exe'))) {
|
||||
throw "Staged ZoiteChat executable is missing from $source"
|
||||
}
|
||||
|
||||
$repoRoot = (Resolve-Path (Join-Path $PSScriptRoot '..\..')).Path
|
||||
$templatePath = Join-Path $PSScriptRoot 'AppxManifest.xml.in'
|
||||
$iconPath = Join-Path $repoRoot 'data\icons\zoitechat.png'
|
||||
|
||||
if (-not (Test-Path $templatePath)) {
|
||||
throw "MSIX manifest template is missing: $templatePath"
|
||||
}
|
||||
if (-not (Test-Path $iconPath)) {
|
||||
throw "ZoiteChat PNG icon is missing: $iconPath"
|
||||
}
|
||||
|
||||
if ([System.IO.Path]::IsPathRooted($OutputPath)) {
|
||||
$output = [System.IO.Path]::GetFullPath($OutputPath)
|
||||
}
|
||||
else {
|
||||
$output = [System.IO.Path]::GetFullPath((Join-Path $PWD $OutputPath))
|
||||
}
|
||||
$outputDirectory = Split-Path $output -Parent
|
||||
New-Item -ItemType Directory -Path $outputDirectory -Force | Out-Null
|
||||
|
||||
$stagingRoot = Join-Path $env:RUNNER_TEMP 'zoitechat-msix'
|
||||
$verifyRoot = Join-Path $env:RUNNER_TEMP 'zoitechat-msix-verify'
|
||||
$pfxPath = Join-Path $env:RUNNER_TEMP 'zoitechat-msix-dev.pfx'
|
||||
|
||||
foreach ($path in @($stagingRoot, $verifyRoot)) {
|
||||
if (Test-Path $path) {
|
||||
Remove-Item -Path $path -Recurse -Force
|
||||
}
|
||||
}
|
||||
if (Test-Path $pfxPath) {
|
||||
Remove-Item -Path $pfxPath -Force
|
||||
}
|
||||
|
||||
New-Item -ItemType Directory -Path $stagingRoot -Force | Out-Null
|
||||
$appRoot = Join-Path $stagingRoot 'ZoiteChat'
|
||||
New-Item -ItemType Directory -Path $appRoot -Force | Out-Null
|
||||
Copy-Item -Path (Join-Path $source '*') -Destination $appRoot -Recurse -Force
|
||||
|
||||
# copy.vcxproj stages everything needed by every Inno component. The Store
|
||||
# package keeps the useful bundled plugins and scripting bridges while letting
|
||||
# the Microsoft Store own application updates. The WinSparkle updater is the
|
||||
# only bundled plugin deliberately removed from the Store package.
|
||||
$excludeFiles = @(
|
||||
'portable-mode',
|
||||
'zoitechat-text.exe',
|
||||
'plugins\hcupd.dll',
|
||||
'WinSparkle.dll',
|
||||
'share\download.png'
|
||||
)
|
||||
|
||||
foreach ($relativePath in $excludeFiles) {
|
||||
$path = Join-Path $appRoot $relativePath
|
||||
if (Test-Path $path) {
|
||||
Remove-Item -Path $path -Force
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($relativePath in @('share\doc\WinSparkle')) {
|
||||
$path = Join-Path $appRoot $relativePath
|
||||
if (Test-Path $path) {
|
||||
Remove-Item -Path $path -Recurse -Force
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($requiredPath in @(
|
||||
'zoitechat.exe',
|
||||
'plugins\hcnotifications-winrt.dll',
|
||||
'plugins\hcchecksum.dll',
|
||||
'plugins\hcexec.dll',
|
||||
'plugins\hcfishlim.dll',
|
||||
'plugins\hcsysinfo.dll',
|
||||
'share\system.png',
|
||||
'share\fonts\zoitechat\NotoColorEmoji.ttf',
|
||||
'share\doc\zoitechat\fonts\OFL.txt',
|
||||
'plugins\hclua.dll',
|
||||
'plugins\hcperl.dll',
|
||||
'plugins\hcpython3.dll',
|
||||
'plugins\hcpython38.dll'
|
||||
)) {
|
||||
if (-not (Test-Path (Join-Path $appRoot $requiredPath))) {
|
||||
throw "MSIX staging is missing required file: $requiredPath"
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($requiredPattern in @('_cffi_backend.cp314*.pyd', '_cffi_backend.cp38*.pyd')) {
|
||||
$match = Get-ChildItem -Path $appRoot -Filter $requiredPattern -File -ErrorAction SilentlyContinue |
|
||||
Select-Object -First 1
|
||||
if ($null -eq $match) {
|
||||
throw "MSIX staging is missing required Python support file: $requiredPattern"
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($requiredPythonFile in @('zoitechat.py', '_zoitechat.py', 'hexchat.py', 'xchat.py')) {
|
||||
$path = Join-Path (Join-Path $appRoot 'python') $requiredPythonFile
|
||||
if (-not (Test-Path $path)) {
|
||||
throw "MSIX staging is missing required Python bridge file: $requiredPythonFile"
|
||||
}
|
||||
}
|
||||
|
||||
$assets = Join-Path $stagingRoot 'Assets'
|
||||
New-Item -ItemType Directory -Path $assets -Force | Out-Null
|
||||
|
||||
$image = [System.Drawing.Image]::FromFile($iconPath)
|
||||
try {
|
||||
New-MsixAsset -SourceImage $image -Width 50 -Height 50 `
|
||||
-Path (Join-Path $assets 'StoreLogo.png')
|
||||
New-MsixAsset -SourceImage $image -Width 44 -Height 44 `
|
||||
-Path (Join-Path $assets 'Square44x44Logo.png')
|
||||
New-MsixAsset -SourceImage $image -Width 150 -Height 150 `
|
||||
-Path (Join-Path $assets 'Square150x150Logo.png')
|
||||
}
|
||||
finally {
|
||||
$image.Dispose()
|
||||
}
|
||||
|
||||
$manifest = Get-Content $templatePath -Raw -Encoding UTF8
|
||||
$manifest = $manifest.Replace('@IDENTITY_NAME@', (Escape-Xml $IdentityName))
|
||||
$manifest = $manifest.Replace('@PUBLISHER@', (Escape-Xml $Publisher))
|
||||
$manifest = $manifest.Replace('@PUBLISHER_DISPLAY_NAME@', (Escape-Xml $PublisherDisplayName))
|
||||
$manifest = $manifest.Replace('@PACKAGE_VERSION@', (Escape-Xml $PackageVersion))
|
||||
|
||||
if ($manifest -match '@[A-Z0-9_]+@') {
|
||||
throw "Unexpanded MSIX manifest placeholder: $($Matches[0])"
|
||||
}
|
||||
|
||||
$manifestPath = Join-Path $stagingRoot 'AppxManifest.xml'
|
||||
[System.IO.File]::WriteAllText(
|
||||
$manifestPath,
|
||||
$manifest,
|
||||
[System.Text.UTF8Encoding]::new($false)
|
||||
)
|
||||
|
||||
# Catch malformed XML before MakeAppx so CI reports a useful error.
|
||||
[xml](Get-Content $manifestPath -Raw -Encoding UTF8) | Out-Null
|
||||
|
||||
$makeAppx = Find-WindowsSdkTool -ToolName 'MakeAppx.exe'
|
||||
$signtool = Find-WindowsSdkTool -ToolName 'SignTool.exe'
|
||||
|
||||
if (Test-Path $output) {
|
||||
Remove-Item -Path $output -Force
|
||||
}
|
||||
|
||||
& $makeAppx pack /d $stagingRoot /p $output /o
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "MakeAppx failed with exit code $LASTEXITCODE"
|
||||
}
|
||||
|
||||
$certificate = $null
|
||||
try {
|
||||
if ($SelfSign) {
|
||||
# Partner Center replaces this development signature with Microsoft's
|
||||
# trusted Store signature. The certificate subject must exactly match
|
||||
# the manifest Publisher for SignTool to accept the package.
|
||||
$certificate = New-SelfSignedCertificate `
|
||||
-Type Custom `
|
||||
-KeyUsage DigitalSignature `
|
||||
-Subject $Publisher `
|
||||
-CertStoreLocation 'Cert:\CurrentUser\My' `
|
||||
-HashAlgorithm SHA256 `
|
||||
-TextExtension @(
|
||||
'2.5.29.37={text}1.3.6.1.5.5.7.3.3',
|
||||
'2.5.29.19={text}'
|
||||
) `
|
||||
-FriendlyName 'ZoiteChat MSIX CI signing certificate'
|
||||
|
||||
if ($certificate.Subject -cne $Publisher) {
|
||||
throw "Generated certificate subject '$($certificate.Subject)' does not exactly match manifest Publisher '$Publisher'."
|
||||
}
|
||||
|
||||
$passwordText = [Guid]::NewGuid().ToString('N')
|
||||
$password = ConvertTo-SecureString -String $passwordText -AsPlainText -Force
|
||||
Export-PfxCertificate -Cert $certificate -FilePath $pfxPath -Password $password | Out-Null
|
||||
|
||||
& $signtool sign /fd SHA256 /f $pfxPath /p $passwordText $output
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "SignTool failed with exit code $LASTEXITCODE"
|
||||
}
|
||||
|
||||
$signature = Get-AuthenticodeSignature -FilePath $output
|
||||
if (-not $signature.SignerCertificate -or
|
||||
$signature.SignerCertificate.Subject -cne $Publisher) {
|
||||
throw 'MSIX signature does not match the manifest Publisher.'
|
||||
}
|
||||
}
|
||||
|
||||
New-Item -ItemType Directory -Path $verifyRoot -Force | Out-Null
|
||||
& $makeAppx unpack /p $output /d $verifyRoot /o
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "MakeAppx validation unpack failed with exit code $LASTEXITCODE"
|
||||
}
|
||||
|
||||
[xml] $verifiedManifest = Get-Content (Join-Path $verifyRoot 'AppxManifest.xml') -Raw -Encoding UTF8
|
||||
$ns = New-Object System.Xml.XmlNamespaceManager($verifiedManifest.NameTable)
|
||||
$ns.AddNamespace('f', 'http://schemas.microsoft.com/appx/manifest/foundation/windows10')
|
||||
$identity = $verifiedManifest.SelectSingleNode('/f:Package/f:Identity', $ns)
|
||||
if (-not $identity) {
|
||||
throw 'Validated MSIX does not contain a package Identity.'
|
||||
}
|
||||
if ($identity.Name -cne $IdentityName -or
|
||||
$identity.Publisher -cne $Publisher -or
|
||||
$identity.Version -cne $PackageVersion) {
|
||||
throw 'Validated MSIX identity does not match the requested Store identity.'
|
||||
}
|
||||
|
||||
foreach ($requiredPath in @(
|
||||
'ZoiteChat\zoitechat.exe',
|
||||
'ZoiteChat\plugins\hcnotifications-winrt.dll',
|
||||
'ZoiteChat\plugins\hcchecksum.dll',
|
||||
'ZoiteChat\plugins\hcexec.dll',
|
||||
'ZoiteChat\plugins\hcfishlim.dll',
|
||||
'ZoiteChat\plugins\hcsysinfo.dll',
|
||||
'ZoiteChat\share\system.png',
|
||||
'ZoiteChat\share\fonts\zoitechat\NotoColorEmoji.ttf',
|
||||
'ZoiteChat\share\doc\zoitechat\fonts\OFL.txt',
|
||||
'ZoiteChat\plugins\hclua.dll',
|
||||
'ZoiteChat\plugins\hcperl.dll',
|
||||
'ZoiteChat\plugins\hcpython3.dll',
|
||||
'ZoiteChat\plugins\hcpython38.dll'
|
||||
)) {
|
||||
if (-not (Test-Path (Join-Path $verifyRoot $requiredPath))) {
|
||||
throw "Validated MSIX is missing required file: $requiredPath"
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($requiredPattern in @('_cffi_backend.cp314*.pyd', '_cffi_backend.cp38*.pyd')) {
|
||||
$match = Get-ChildItem -Path (Join-Path $verifyRoot 'ZoiteChat') -Filter $requiredPattern -File -ErrorAction SilentlyContinue |
|
||||
Select-Object -First 1
|
||||
if ($null -eq $match) {
|
||||
throw "Validated MSIX is missing required Python support file: $requiredPattern"
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($requiredPythonFile in @('zoitechat.py', '_zoitechat.py', 'hexchat.py', 'xchat.py')) {
|
||||
$path = Join-Path (Join-Path $verifyRoot 'ZoiteChat\python') $requiredPythonFile
|
||||
if (-not (Test-Path $path)) {
|
||||
throw "Validated MSIX is missing required Python bridge file: $requiredPythonFile"
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($excludedPath in @(
|
||||
'ZoiteChat\portable-mode',
|
||||
'ZoiteChat\zoitechat-text.exe',
|
||||
'ZoiteChat\plugins\hcupd.dll',
|
||||
'ZoiteChat\WinSparkle.dll',
|
||||
'ZoiteChat\share\download.png'
|
||||
)) {
|
||||
if (Test-Path (Join-Path $verifyRoot $excludedPath)) {
|
||||
throw "MSIX incorrectly contains excluded file/directory: $excludedPath"
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
if ($certificate) {
|
||||
Remove-Item -Path "Cert:\CurrentUser\My\$($certificate.Thumbprint)" -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
if (Test-Path $pfxPath) {
|
||||
Remove-Item -Path $pfxPath -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
foreach ($path in @($stagingRoot, $verifyRoot)) {
|
||||
if (Test-Path $path) {
|
||||
Remove-Item -Path $path -Recurse -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (-not (Test-Path $output)) {
|
||||
throw "Expected MSIX was not created: $output"
|
||||
}
|
||||
|
||||
Write-Host "Created MSIX: $output"
|
||||
@@ -0,0 +1,162 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
|
||||
<!--
|
||||
This MSI intentionally mirrors the staged portion of the normal Inno Setup
|
||||
payload. Optional/custom-only files are excluded below. In particular,
|
||||
portable-mode must never be harvested because copy.vcxproj always stages
|
||||
that marker. Inno-only download-at-install components remain outside the MSI.
|
||||
-->
|
||||
<Package
|
||||
Name="ZoiteChat"
|
||||
Manufacturer="ZoiteChat"
|
||||
Version="$(ProductVersion)"
|
||||
UpgradeCode="{E9F09DF3-12FA-4BDF-A8AA-A6D62A327ED5}"
|
||||
Scope="perMachine"
|
||||
InstallerVersion="500"
|
||||
Compressed="yes">
|
||||
|
||||
<MajorUpgrade
|
||||
AllowSameVersionUpgrades="yes"
|
||||
DowngradeErrorMessage="A newer version of ZoiteChat is already installed." />
|
||||
|
||||
<MediaTemplate EmbedCab="yes" CompressionLevel="high" />
|
||||
|
||||
<Icon Id="ZoiteChat.ico" SourceFile="$(sys.SOURCEFILEDIR)..\..\data\icons\zoitechat.ico" />
|
||||
<Property Id="ARPPRODUCTICON" Value="ZoiteChat.ico" />
|
||||
<Property Id="ARPHELPLINK" Value="https://github.com/ZoiteChat/zoitechat/issues" />
|
||||
<Property Id="ARPURLINFOABOUT" Value="https://zoitechat.org/" />
|
||||
<Property Id="ARPURLUPDATEINFO" Value="https://zoitechat.org/downloads.html" />
|
||||
<Property Id="ARPNOMODIFY" Value="1" />
|
||||
|
||||
<!--
|
||||
The Inno installer can bootstrap the VC++ runtime. A plain MSI should not
|
||||
run an EXE prerequisite as an MSI custom action, so require the runtime.
|
||||
Administrative extraction is allowed regardless of prerequisite state.
|
||||
-->
|
||||
<Property Id="VCREDIST_X64_INSTALLED">
|
||||
<RegistrySearch
|
||||
Id="FindVCRedistX64"
|
||||
Root="HKLM"
|
||||
Key="SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x64"
|
||||
Name="Installed"
|
||||
Type="raw"
|
||||
Bitness="always64" />
|
||||
</Property>
|
||||
<Launch
|
||||
Condition="Installed OR ACTION = "ADMIN" OR VCREDIST_X64_INSTALLED = "#1""
|
||||
Message="Microsoft Visual C++ 2015-2022 x64 Redistributable is required before installing ZoiteChat." />
|
||||
<Launch
|
||||
Condition="Installed OR ACTION = "ADMIN" OR VersionNT64 > 601 OR (VersionNT64 = 601 AND ServicePackLevel >= 1)"
|
||||
Message="ZoiteChat requires 64-bit Windows 7 SP1 or later." />
|
||||
|
||||
<StandardDirectory Id="ProgramFiles6432Folder">
|
||||
<Directory Id="INSTALLFOLDER" Name="ZoiteChat" />
|
||||
</StandardDirectory>
|
||||
|
||||
<StandardDirectory Id="ProgramMenuFolder">
|
||||
<Directory Id="ApplicationProgramsFolder" Name="ZoiteChat" />
|
||||
</StandardDirectory>
|
||||
|
||||
<Feature Id="MainFeature" Title="ZoiteChat" Level="1">
|
||||
<ComponentGroupRef Id="ApplicationFiles" />
|
||||
<ComponentRef Id="StartMenuShortcuts" />
|
||||
<ComponentRef Id="ProtocolAndThemeAssociations" />
|
||||
</Feature>
|
||||
</Package>
|
||||
|
||||
<Fragment>
|
||||
<ComponentGroup Id="ApplicationFiles">
|
||||
<Files Directory="INSTALLFOLDER" Include="$(SourceDir)\**">
|
||||
<!-- Created by copy.vcxproj for Inno's optional portable task only. -->
|
||||
<Exclude Files="$(SourceDir)\portable-mode" />
|
||||
<!-- Inno custom-only application component. -->
|
||||
<Exclude Files="$(SourceDir)\zoitechat-text.exe" />
|
||||
<!--
|
||||
Keep the bundled utility and scripting plugins, including Python
|
||||
3.14 and 3.8 support, available to non-Inno installations.
|
||||
-->
|
||||
</Files>
|
||||
</ComponentGroup>
|
||||
</Fragment>
|
||||
|
||||
<Fragment>
|
||||
<Component Id="StartMenuShortcuts" Directory="ApplicationProgramsFolder" Guid="*">
|
||||
<Shortcut
|
||||
Id="ZoiteChatShortcut"
|
||||
Name="ZoiteChat"
|
||||
Description="ZoiteChat IRC client"
|
||||
Target="[INSTALLFOLDER]zoitechat.exe"
|
||||
WorkingDirectory="INSTALLFOLDER"
|
||||
Icon="ZoiteChat.ico">
|
||||
<ShortcutProperty Key="System.AppUserModel.ID" Value="ZoiteChat.Desktop.Notify" />
|
||||
</Shortcut>
|
||||
|
||||
<Shortcut
|
||||
Id="ZoiteChatSafeModeShortcut"
|
||||
Name="ZoiteChat Safe Mode"
|
||||
Description="Start ZoiteChat without auto-connect or plugins"
|
||||
Target="[INSTALLFOLDER]zoitechat.exe"
|
||||
Arguments="--no-auto --no-plugins"
|
||||
WorkingDirectory="INSTALLFOLDER"
|
||||
Icon="ZoiteChat.ico" />
|
||||
|
||||
<Shortcut
|
||||
Id="ZoiteChatChangelogShortcut"
|
||||
Name="ZoiteChat ChangeLog"
|
||||
Target="[INSTALLFOLDER]changelog.url" />
|
||||
|
||||
<Shortcut
|
||||
Id="ZoiteChatReadmeShortcut"
|
||||
Name="ZoiteChat ReadMe"
|
||||
Target="[INSTALLFOLDER]readme.url" />
|
||||
|
||||
<Shortcut
|
||||
Id="ZoiteChatUninstallShortcut"
|
||||
Name="Uninstall ZoiteChat"
|
||||
Target="[System64Folder]msiexec.exe"
|
||||
Arguments="/x [ProductCode]" />
|
||||
|
||||
<RemoveFolder Id="RemoveApplicationProgramsFolder" On="uninstall" />
|
||||
<RegistryValue
|
||||
Root="HKLM"
|
||||
Key="Software\ZoiteChat\Installer"
|
||||
Name="StartMenuShortcuts"
|
||||
Type="integer"
|
||||
Value="1"
|
||||
KeyPath="yes" />
|
||||
</Component>
|
||||
</Fragment>
|
||||
|
||||
<Fragment>
|
||||
<Component Id="ProtocolAndThemeAssociations" Directory="INSTALLFOLDER" Guid="*">
|
||||
<RegistryValue
|
||||
Root="HKCR"
|
||||
Key="irc"
|
||||
Type="string"
|
||||
Value="URL:IRC Protocol"
|
||||
KeyPath="yes" />
|
||||
<RegistryValue Root="HKCR" Key="irc" Name="URL Protocol" Type="string" Value="" />
|
||||
<RegistryValue Root="HKCR" Key="irc\DefaultIcon" Type="string" Value="[INSTALLFOLDER]zoitechat.exe,0" />
|
||||
<RegistryValue Root="HKCR" Key="irc\shell" Type="string" Value="open" />
|
||||
<RegistryValue
|
||||
Root="HKCR"
|
||||
Key="irc\shell\open\command"
|
||||
Type="string"
|
||||
Value=""[INSTALLFOLDER]zoitechat.exe" --url="%1"" />
|
||||
|
||||
<RegistryValue Root="HKCR" Key=".zct" Type="string" Value="ZoiteChat.Theme" />
|
||||
<RegistryValue Root="HKCR" Key=".hct" Type="string" Value="ZoiteChat.Theme" />
|
||||
<RegistryValue Root="HKCR" Key="ZoiteChat.Theme" Type="string" Value="ZoiteChat Theme" />
|
||||
<RegistryValue
|
||||
Root="HKCR"
|
||||
Key="ZoiteChat.Theme\DefaultIcon"
|
||||
Type="string"
|
||||
Value="[INSTALLFOLDER]zoitechat.exe,0" />
|
||||
<RegistryValue
|
||||
Root="HKCR"
|
||||
Key="ZoiteChat.Theme\shell\open\command"
|
||||
Type="string"
|
||||
Value=""[INSTALLFOLDER]zoitechat.exe" "%1"" />
|
||||
</Component>
|
||||
</Fragment>
|
||||
</Wix>
|
||||
Reference in New Issue
Block a user