Add release build configuration and MSI installer
- Configure self-contained, single-file release build - Add version and company metadata to project - Fix Assembly.Location for single-file compatibility (use AppContext.BaseDirectory) - Add Resources folder copy to publish output - Create WiX installer project with Product.wxs - Configure auto-start via HKCU Run registry key - Add build-release.ps1 PowerShell script for automated builds - MSI installer installs to %LOCALAPPDATA%\DangerousThings\NFC Actions - Creates Start Menu shortcut - Automatically starts application on user login 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
35
Installer/Installer.wixproj
Normal file
35
Installer/Installer.wixproj
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" DefaultTargets="Build" InitialTargets="EnsureWixToolsetInstalled" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
|
||||||
|
<ProductVersion>3.11</ProductVersion>
|
||||||
|
<ProjectGuid>f5e6a7b8-c9d0-4e1f-2a3b-4c5d6e7f8a9b</ProjectGuid>
|
||||||
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
|
<OutputName>NfcActions-Setup</OutputName>
|
||||||
|
<OutputType>Package</OutputType>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||||
|
<OutputPath>bin\$(Configuration)\</OutputPath>
|
||||||
|
<IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
|
||||||
|
<DefineConstants>Debug</DefineConstants>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||||
|
<OutputPath>bin\$(Configuration)\</OutputPath>
|
||||||
|
<IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="Product.wxs" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<WixExtension Include="WixUIExtension">
|
||||||
|
<HintPath>$(WixExtDir)\WixUIExtension.dll</HintPath>
|
||||||
|
<Name>WixUIExtension</Name>
|
||||||
|
</WixExtension>
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(WixTargetsPath)" Condition=" '$(WixTargetsPath)' != '' " />
|
||||||
|
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets" Condition=" '$(WixTargetsPath)' == '' AND Exists('$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets') " />
|
||||||
|
<Target Name="EnsureWixToolsetInstalled" Condition=" '$(WixTargetsImported)' != 'true' ">
|
||||||
|
<Error Text="The WiX Toolset v3.11 (or newer) build tools must be installed to build this project. To download the WiX Toolset, see http://wixtoolset.org/releases/" />
|
||||||
|
</Target>
|
||||||
|
</Project>
|
||||||
101
Installer/Product.wxs
Normal file
101
Installer/Product.wxs
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
|
||||||
|
<Product Id="*"
|
||||||
|
Name="NFC Actions"
|
||||||
|
Language="1033"
|
||||||
|
Version="1.0.0.0"
|
||||||
|
Manufacturer="Dangerous Things"
|
||||||
|
UpgradeCode="A1B2C3D4-E5F6-4A5B-8C9D-0E1F2A3B4C5D">
|
||||||
|
|
||||||
|
<Package InstallerVersion="200"
|
||||||
|
Compressed="yes"
|
||||||
|
InstallScope="perUser"
|
||||||
|
Description="NFC Actions - NFC card reader monitoring and automation"
|
||||||
|
Comments="Visit dangerousthings.com for more information" />
|
||||||
|
|
||||||
|
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
|
||||||
|
<MediaTemplate EmbedCab="yes" />
|
||||||
|
|
||||||
|
<!-- Suppress ICE validation warnings for per-user installation -->
|
||||||
|
<Property Id="DISABLEADVTSHORTCUTS" Value="1" />
|
||||||
|
<Property Id="MSIINSTALLPERUSER" Value="1" />
|
||||||
|
|
||||||
|
<Icon Id="ProductIcon" SourceFile="..\NfcActions\Resources\icon.ico" />
|
||||||
|
<Property Id="ARPPRODUCTICON" Value="ProductIcon" />
|
||||||
|
<Property Id="ARPHELPLINK" Value="https://dangerousthings.com" />
|
||||||
|
<Property Id="ARPURLINFOABOUT" Value="https://dangerousthings.com" />
|
||||||
|
|
||||||
|
<Feature Id="ProductFeature" Title="NFC Actions" Level="1">
|
||||||
|
<ComponentGroupRef Id="ProductComponents" />
|
||||||
|
<ComponentRef Id="ApplicationShortcut" />
|
||||||
|
<ComponentRef Id="AutoStartRegistry" />
|
||||||
|
</Feature>
|
||||||
|
|
||||||
|
<Directory Id="TARGETDIR" Name="SourceDir">
|
||||||
|
<Directory Id="LocalAppDataFolder">
|
||||||
|
<Directory Id="CompanyFolder" Name="DangerousThings">
|
||||||
|
<Directory Id="INSTALLFOLDER" Name="NFC Actions" />
|
||||||
|
</Directory>
|
||||||
|
</Directory>
|
||||||
|
|
||||||
|
<Directory Id="ProgramMenuFolder">
|
||||||
|
<Directory Id="ApplicationProgramsFolder" Name="NFC Actions"/>
|
||||||
|
</Directory>
|
||||||
|
</Directory>
|
||||||
|
|
||||||
|
<DirectoryRef Id="ApplicationProgramsFolder">
|
||||||
|
<Component Id="ApplicationShortcut" Guid="B2C3D4E5-F6A7-4B6C-9D0E-1F2A3B4C5D6E">
|
||||||
|
<Shortcut Id="ApplicationStartMenuShortcut"
|
||||||
|
Name="NFC Actions"
|
||||||
|
Description="NFC card reader monitoring and automation"
|
||||||
|
Target="[INSTALLFOLDER]NfcActions.exe"
|
||||||
|
WorkingDirectory="INSTALLFOLDER"
|
||||||
|
Icon="ProductIcon" />
|
||||||
|
<RemoveFolder Id="CleanUpShortCut" Directory="ApplicationProgramsFolder" On="uninstall"/>
|
||||||
|
<RegistryValue Root="HKCU"
|
||||||
|
Key="Software\DangerousThings\NfcActions"
|
||||||
|
Name="installed"
|
||||||
|
Type="integer"
|
||||||
|
Value="1"
|
||||||
|
KeyPath="yes"/>
|
||||||
|
</Component>
|
||||||
|
</DirectoryRef>
|
||||||
|
|
||||||
|
<DirectoryRef Id="INSTALLFOLDER">
|
||||||
|
<Component Id="AutoStartRegistry" Guid="C3D4E5F6-A7B8-4C7D-0E1F-2A3B4C5D6E7F">
|
||||||
|
<RegistryValue Root="HKCU"
|
||||||
|
Key="Software\Microsoft\Windows\CurrentVersion\Run"
|
||||||
|
Name="NFC Actions"
|
||||||
|
Type="string"
|
||||||
|
Value=""[INSTALLFOLDER]NfcActions.exe""
|
||||||
|
KeyPath="yes"/>
|
||||||
|
</Component>
|
||||||
|
</DirectoryRef>
|
||||||
|
|
||||||
|
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
|
||||||
|
<Component Id="MainExecutable" Guid="D4E5F6A7-B8C9-4D8E-1F2A-3B4C5D6E7F8A">
|
||||||
|
<File Id="NfcActionsExe"
|
||||||
|
Source="..\NfcActions\bin\Release\net7.0-windows\win-x64\publish\NfcActions.exe" />
|
||||||
|
<RegistryValue Root="HKCU"
|
||||||
|
Key="Software\DangerousThings\NfcActions"
|
||||||
|
Name="MainExe"
|
||||||
|
Type="integer"
|
||||||
|
Value="1"
|
||||||
|
KeyPath="yes"/>
|
||||||
|
<RemoveFolder Id="RemoveINSTALLFOLDER" Directory="INSTALLFOLDER" On="uninstall" />
|
||||||
|
<RemoveFolder Id="RemoveCompanyFolder" Directory="CompanyFolder" On="uninstall" />
|
||||||
|
</Component>
|
||||||
|
|
||||||
|
<Component Id="ResourcesFolder" Guid="E5F6A7B8-C9D0-4E9F-2A3B-4C5D6E7F8A9B">
|
||||||
|
<File Id="IconIco" Source="..\NfcActions\bin\Release\net7.0-windows\win-x64\publish\Resources\icon.ico" />
|
||||||
|
<RegistryValue Root="HKCU"
|
||||||
|
Key="Software\DangerousThings\NfcActions"
|
||||||
|
Name="Resources"
|
||||||
|
Type="integer"
|
||||||
|
Value="1"
|
||||||
|
KeyPath="yes"/>
|
||||||
|
</Component>
|
||||||
|
</ComponentGroup>
|
||||||
|
|
||||||
|
</Product>
|
||||||
|
</Wix>
|
||||||
@@ -7,6 +7,21 @@
|
|||||||
<UseWPF>true</UseWPF>
|
<UseWPF>true</UseWPF>
|
||||||
<UseWindowsForms>true</UseWindowsForms>
|
<UseWindowsForms>true</UseWindowsForms>
|
||||||
<ApplicationIcon>Resources\icon.ico</ApplicationIcon>
|
<ApplicationIcon>Resources\icon.ico</ApplicationIcon>
|
||||||
|
<Version>1.0.0</Version>
|
||||||
|
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||||
|
<FileVersion>1.0.0.0</FileVersion>
|
||||||
|
<Company>Dangerous Things</Company>
|
||||||
|
<Product>NFC Actions</Product>
|
||||||
|
<Description>NFC card reader monitoring and action automation</Description>
|
||||||
|
<Copyright>Copyright © 2025 Dangerous Things</Copyright>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition="'$(Configuration)'=='Release'">
|
||||||
|
<PublishSingleFile>true</PublishSingleFile>
|
||||||
|
<SelfContained>true</SelfContained>
|
||||||
|
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||||
|
<PublishReadyToRun>true</PublishReadyToRun>
|
||||||
|
<IncludeNativeLibrariesForSelfExtract>true</IncludeNativeLibrariesForSelfExtract>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -22,7 +37,18 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="Resources\icon.ico" CopyToOutputDirectory="PreserveNewest" />
|
<None Include="Resources\**\*">
|
||||||
|
<Link>Resources\%(RecursiveDir)%(Filename)%(Extension)</Link>
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<Target Name="CopyResourcesOnPublish" AfterTargets="Publish">
|
||||||
|
<ItemGroup>
|
||||||
|
<ResourceFiles Include="$(ProjectDir)Resources\**\*" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Copy SourceFiles="@(ResourceFiles)" DestinationFolder="$(PublishDir)Resources\%(RecursiveDir)" SkipUnchangedFiles="true" />
|
||||||
|
</Target>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -21,9 +21,8 @@ public class LogService
|
|||||||
{
|
{
|
||||||
_syncContext = SynchronizationContext.Current;
|
_syncContext = SynchronizationContext.Current;
|
||||||
|
|
||||||
// Create log file in the same directory as the executable
|
// Create log file in the app directory (works for single-file publish)
|
||||||
var exePath = Assembly.GetExecutingAssembly().Location;
|
var exeDir = AppContext.BaseDirectory;
|
||||||
var exeDir = Path.GetDirectoryName(exePath) ?? Environment.CurrentDirectory;
|
|
||||||
var timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss");
|
var timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss");
|
||||||
_logFilePath = Path.Combine(exeDir, $"nfc-actions-debug-{timestamp}.log");
|
_logFilePath = Path.Combine(exeDir, $"nfc-actions-debug-{timestamp}.log");
|
||||||
|
|
||||||
|
|||||||
112
build-release.ps1
Normal file
112
build-release.ps1
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
# NFC Actions Release Build Script
|
||||||
|
# This script builds the release version and optionally creates an installer
|
||||||
|
|
||||||
|
param(
|
||||||
|
[switch]$SkipBuild = $false,
|
||||||
|
[switch]$BuildInstaller = $true
|
||||||
|
)
|
||||||
|
|
||||||
|
$ErrorActionPreference = "Stop"
|
||||||
|
$scriptPath = Split-Path -Parent $MyInvocation.MyCommand.Path
|
||||||
|
$projectPath = Join-Path $scriptPath "NfcActions\NfcActions.csproj"
|
||||||
|
$publishPath = Join-Path $scriptPath "NfcActions\bin\Release\net7.0-windows\win-x64\publish"
|
||||||
|
$installerPath = Join-Path $scriptPath "Installer"
|
||||||
|
|
||||||
|
Write-Host "=== NFC Actions Release Build ===" -ForegroundColor Cyan
|
||||||
|
Write-Host ""
|
||||||
|
|
||||||
|
# Step 1: Build and publish the application
|
||||||
|
if (-not $SkipBuild) {
|
||||||
|
Write-Host "[1/4] Cleaning previous builds..." -ForegroundColor Yellow
|
||||||
|
dotnet clean $projectPath -c Release -v quiet
|
||||||
|
|
||||||
|
Write-Host "[2/4] Building release (self-contained, single-file)..." -ForegroundColor Yellow
|
||||||
|
dotnet publish $projectPath -c Release -r win-x64 --self-contained true /p:PublishSingleFile=true /p:IncludeNativeLibrariesForSelfExtract=true /p:PublishReadyToRun=true
|
||||||
|
|
||||||
|
if ($LASTEXITCODE -ne 0) {
|
||||||
|
Write-Host "Build failed!" -ForegroundColor Red
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "Build completed successfully!" -ForegroundColor Green
|
||||||
|
Write-Host "Output: $publishPath" -ForegroundColor Gray
|
||||||
|
Write-Host ""
|
||||||
|
}
|
||||||
|
|
||||||
|
# Step 2: Check if WiX is available
|
||||||
|
if ($BuildInstaller) {
|
||||||
|
Write-Host "[3/4] Checking for WiX Toolset..." -ForegroundColor Yellow
|
||||||
|
|
||||||
|
$wixInstalled = $false
|
||||||
|
$candle = Get-Command candle.exe -ErrorAction SilentlyContinue
|
||||||
|
$light = Get-Command light.exe -ErrorAction SilentlyContinue
|
||||||
|
|
||||||
|
if ($candle -and $light) {
|
||||||
|
$wixInstalled = $true
|
||||||
|
Write-Host "WiX Toolset found!" -ForegroundColor Green
|
||||||
|
} else {
|
||||||
|
Write-Host "WiX Toolset not found in PATH" -ForegroundColor Yellow
|
||||||
|
|
||||||
|
# Check common installation paths
|
||||||
|
$wixPaths = @(
|
||||||
|
"C:\Program Files (x86)\WiX Toolset v3.11\bin",
|
||||||
|
"C:\Program Files (x86)\WiX Toolset v3.14\bin",
|
||||||
|
"C:\Program Files\WiX Toolset v3.11\bin",
|
||||||
|
"C:\Program Files\WiX Toolset v3.14\bin"
|
||||||
|
)
|
||||||
|
|
||||||
|
foreach ($path in $wixPaths) {
|
||||||
|
if (Test-Path (Join-Path $path "candle.exe")) {
|
||||||
|
$env:Path += ";$path"
|
||||||
|
$wixInstalled = $true
|
||||||
|
Write-Host "Found WiX at: $path" -ForegroundColor Green
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($wixInstalled) {
|
||||||
|
Write-Host "[4/4] Building MSI installer..." -ForegroundColor Yellow
|
||||||
|
|
||||||
|
Push-Location $installerPath
|
||||||
|
|
||||||
|
# Run candle (compile)
|
||||||
|
& candle.exe Product.wxs -out obj\Product.wixobj
|
||||||
|
if ($LASTEXITCODE -ne 0) {
|
||||||
|
Pop-Location
|
||||||
|
Write-Host "Candle (WiX compile) failed!" -ForegroundColor Red
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Run light (link)
|
||||||
|
& light.exe obj\Product.wixobj -out bin\NfcActions-Setup.msi -ext WixUIExtension
|
||||||
|
if ($LASTEXITCODE -ne 0) {
|
||||||
|
Pop-Location
|
||||||
|
Write-Host "Light (WiX link) failed!" -ForegroundColor Red
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Pop-Location
|
||||||
|
|
||||||
|
$msiPath = Join-Path $installerPath "bin\NfcActions-Setup.msi"
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "=== Build Complete ===" -ForegroundColor Green
|
||||||
|
Write-Host "MSI Installer: $msiPath" -ForegroundColor Cyan
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "WiX Toolset not found. Skipping MSI creation." -ForegroundColor Yellow
|
||||||
|
Write-Host "To build the MSI installer, install WiX Toolset from:" -ForegroundColor Yellow
|
||||||
|
Write-Host " https://github.com/wixtoolset/wix3/releases" -ForegroundColor Gray
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "=== Build Complete ===" -ForegroundColor Green
|
||||||
|
Write-Host "Executable: $publishPath\NfcActions.exe" -ForegroundColor Cyan
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Write-Host "[3/4] Skipping installer build" -ForegroundColor Yellow
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "=== Build Complete ===" -ForegroundColor Green
|
||||||
|
Write-Host "Executable: $publishPath\NfcActions.exe" -ForegroundColor Cyan
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host ""
|
||||||
Reference in New Issue
Block a user