Files
RemSound/src/RemSound.App/RemSound.App.csproj
T

142 lines
9.3 KiB
XML
Raw Normal View History

2026-05-13 15:08:31 +01:00
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net10.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UseWindowsForms>true</UseWindowsForms>
<RootNamespace>RemSound.App</RootNamespace>
<AssemblyName>RemSound</AssemblyName>
<ApplicationManifest>app.manifest</ApplicationManifest>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<ApplicationHighDpiMode>SystemAware</ApplicationHighDpiMode>
<!-- Release version. The self-updater (RemSoundUpdater) compares this against the
tag_name on the latest GitHub release; bump it on every public release. The
AssemblyVersion / FileVersion default to this value, and Assembly.GetName().Version
is what the About dialog and the updater both read. -->
<Version>4.8</Version>
2026-05-13 15:08:31 +01:00
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\RemSound.Core\RemSound.Core.csproj" />
<ProjectReference Include="..\RemSound.Sender\RemSound.Sender.csproj" />
<ProjectReference Include="..\RemSound.Receiver\RemSound.Receiver.csproj" />
<PackageReference Include="NAudio" Version="2.3.0" />
<!-- LAME wrapper for MP3 encoding. Pulled in for the recording feature. The native
libmp3lame.dll ships with the package and is copied to the output folder. -->
<PackageReference Include="NAudio.Lame" Version="2.1.0" />
<!-- OGG container writer that wraps Concentus-encoded Opus. Same Concentus the wire
path already uses (transitive dep), so the recording-side OGG-Opus output is
byte-for-byte the same encoder we'd send on a live Opus stream. -->
<PackageReference Include="Concentus.Oggfile" Version="1.0.7" />
<!-- Pure-managed FLAC encoder (Flake). Same encoder CUETools uses; no native DLL,
no P/Invoke. Lossless, ships as managed IL, smaller files than WAV (~50%) without
sample-data loss. -->
<PackageReference Include="CUETools.Codecs.FLAKE" Version="1.0.5" />
<!-- UPnP / NAT-PMP / PCP client library for automatically opening the audio port on
the user's router so peers on the public internet can reach this machine without
manual port forwarding. Cross-protocol — picks whichever the router speaks. Used
under the AppConfig.UpnpEnabled toggle, off by default. -->
<PackageReference Include="Mono.Nat" Version="3.0.4" />
<!-- Native libopus binaries that Concentus 2.0+ auto-detects at runtime and routes
encode/decode calls through. Without this package Concentus uses its pure-managed
C# fallback, which `new`s ~15 working buffers per encode call (issue #22 on the
Concentus repo, open since 2018) and produces ~4.5 MB/s of GC pressure per
encoding lane at 10 ms frames. Switching to native via this package keeps the
encoder state allocated once (C-side) and reuses it across calls. Same encoder
settings, bit-for-bit identical audio output. Installed at the top-level project
(per the package's install guidance) so `dotnet publish` correctly trims native
binaries for irrelevant RIDs from the release output. 2026-05-23. -->
<PackageReference Include="Concentus.Native" Version="1.5.2" />
<!-- Explicit pin for the transitive Concentus.Native.NetCore. The parent package
declares a minimum version of 1.5.1, but 1.5.1 was never published to nuget.org —
only 1.5.2 was. NuGet still resolves correctly (it picks 1.5.2) but emits NU1603
as a warning, which our TreatWarningsAsErrors policy promotes to an error.
Pinning explicitly skips that warning and is self-documenting. -->
<PackageReference Include="Concentus.Native.NetCore" Version="1.5.2" />
2026-05-13 15:08:31 +01:00
</ItemGroup>
<ItemGroup>
<!-- Shipped DEFAULT cue sounds live in a "default sounds\" subfolder under the build/publish
output (2026-06-13: moved out of the per-user folder, which never overwrote them, so a
changed default sound could never reach an existing user). They are part of the install:
the auto-updater (and a dev republish) always overwrites this folder, so a tweaked default
always lands. The user's OWN custom sounds are NOT here - they're explicit file paths set
via the Preferences Browse picker, which the updater never touches. Every WAV in the source
"default sounds\" folder ships via a wildcard (numbered variants, key clicks, passkey), so
adding sounds later needs no csproj change. Spaces in filenames are preserved verbatim. The
EnsureCueSoundsPublished target below guarantees they reach a PUBLISH output even when
MSBuild's incremental Content-copy marker would skip them. -->
<Content Include="..\..\default sounds\*.wav">
<Link>default sounds\%(Filename)%(Extension)</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
2026-05-13 15:08:31 +01:00
<!-- User manual. F1 anywhere in the app opens this via the user's default browser
(HelpLauncher.OpenManual). The PreserveNewest mode means a fresh publish overwrites
the published copy whenever the source is newer; manually-edited copies inside
publish/ get clobbered, which is correct (publish is build output, not config). -->
<Content Include="..\..\readme.html">
<Link>readme.html</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<!-- Tolk screen-reader output DLLs (vendored 2026-06-19). Native libraries P/Invoked by
TolkScreenReaderOutput so RemSound can speak the status line aloud on demand (issue #13) —
needed because a GLOBAL hotkey fires while RemSound isn't focused, where NVDA won't read
anything itself. Tolk.dll loads its two helper DLLs from the same folder, so all three ship
flat next to the exe. Copied on build AND publish; the EnsureTolkDllsPublished target below
makes the publish copy marker-independent (the same belt-and-braces the cue WAVs use). -->
<Content Include="..\..\tolk\Tolk.dll;..\..\tolk\nvdaControllerClient64.dll;..\..\tolk\SAAPI64.dll;..\..\tolk\LICENSE-Tolk.txt">
<Link>%(Filename)%(Extension)</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<!-- Install Scripts (vendored). A .cmd / .ps1 that install the .NET 10 Desktop Runtime RemSound
needs, via winget, for the rare machine that doesn't have it yet. RemSound is a .NET 10 app, so
it can't install its own runtime — it can't start without it — hence a plain script (cmd/ps1
run on what's already in Windows). Shipped next to the exe in an "Install Scripts" folder; the
manual points users here if RemSound won't start. EnsureInstallScriptsPublished below makes the
publish copy marker-independent (same belt-and-braces as the cue WAVs / Tolk DLLs). -->
<Content Include="..\..\Install Scripts\*.cmd;..\..\Install Scripts\*.ps1">
<Link>Install Scripts\%(Filename)%(Extension)</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
2026-05-13 15:08:31 +01:00
</ItemGroup>
<!-- Guarantee the cue WAVs land in a PUBLISHED build. The Content items above use
CopyToOutputDirectory=PreserveNewest, but MSBuild's incremental "copy already done" marker
(obj\...\.csproj.CopyComplete) can skip that copy when publishing into a fresh output folder
whose marker is up to date — which silently shipped the v3.9 zip with NO cue sounds at all.
This explicit post-publish copy is marker-independent: it always copies every WAV from the
source "default sounds\" folder into the published "default sounds\" folder. Build-release.ps1
zips the publish output, so this is what makes the release reliably contain the sounds. (The
self-test "Bundled resources present" step verifies it.) -->
<Target Name="EnsureCueSoundsPublished" AfterTargets="Publish">
<ItemGroup>
<_CueWavs Include="..\..\default sounds\*.wav" />
</ItemGroup>
<Copy SourceFiles="@(_CueWavs)"
DestinationFolder="$(PublishDir)default sounds"
SkipUnchangedFiles="false" />
</Target>
<!-- Same marker-independent guarantee for the Tolk DLLs: always copy them into a PUBLISHED build
so a release zip can never ship without the screen-reader libraries the "speak status line"
feature needs. -->
<Target Name="EnsureTolkDllsPublished" AfterTargets="Publish">
<ItemGroup>
<_TolkFiles Include="..\..\tolk\Tolk.dll;..\..\tolk\nvdaControllerClient64.dll;..\..\tolk\SAAPI64.dll;..\..\tolk\LICENSE-Tolk.txt" />
</ItemGroup>
<Copy SourceFiles="@(_TolkFiles)" DestinationFolder="$(PublishDir)" SkipUnchangedFiles="false" />
</Target>
<!-- Same marker-independent guarantee for the install scripts: always land them in a PUBLISHED build
so a release zip can never ship without the "Install Scripts" folder the manual points to. -->
<Target Name="EnsureInstallScriptsPublished" AfterTargets="Publish">
<ItemGroup>
<_InstallScripts Include="..\..\Install Scripts\*.cmd;..\..\Install Scripts\*.ps1" />
</ItemGroup>
<Copy SourceFiles="@(_InstallScripts)" DestinationFolder="$(PublishDir)Install Scripts" SkipUnchangedFiles="false" />
</Target>
2026-05-13 15:08:31 +01:00
</Project>