You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Migrate to .NET 10 LTS, three months ahead of the .NET 8 deadline
.NET 8 goes out of support on 10 November 2026 and .NET 9 dies the same day,
so .NET 10 LTS (EOL 14 November 2028) was the only target. This was the
hardest date on the roadmap: after it, the installer would ship an
unsupported runtime, a runtime CVE would be unpatchable, and it would show
up as an EOL component in our own SBOM.
What moved
* All nine projects retargeted to net10.0-windows: ControlPanel,
ControlPanel.Core, ControlPanel.Tests, DBSetup, DBSetupQuick, DBUpdater,
DataDirectorySynchronizer, ImportTool, Shared.
* global.json added, pinning SDK 10.0.303 with rollForward latestFeature.
There was no global.json before, which meant installing any newer SDK on a
build machine silently changed the toolchain. It now accepts 10.0.3xx and
later within .NET 10 but never rolls to .NET 11 - that has to be a
deliberate edit, alongside the TargetFramework values and the bundled
runtime.
* The bundled Desktop Runtime moves to 10.x, and get-dotnet-runtime.ps1 is
parameterised by channel and now fails loudly if aka.ms hands back
something under 40 MB. It previously would have saved an error page as the
installer and failed silently at install time.
* hMailServerInnoExtension.iss: the DotNetDesktopMissing() probe globbed
Microsoft.WindowsDesktop.App\8.* and now globs 10.*. Left unchanged it
would have found the .NET 8 runtime, concluded nothing needed installing,
and shipped a Control Panel that could not start.
* section_files_64.iss, section_run.iss and the progress text follow the
new filename.
* capture-cp.ps1 had the net8.0-windows output path hardcoded.
* AGENTS.md, README.md and CONTROL-PANEL-PLAN.md updated. AGENTS.md was also
stale on two counts unrelated to this work - it still claimed 6.2.8 build
10 and 898/898 tests; it now says 6.2.18 build 20 and 1049/1049.
Two real findings, not just retargeting
* .NET 9 added the WFO1000 WinForms analyzer, and with warnings-as-errors it
failed the build on four properties of Shared/Controls/ucText.cs whose
designer-serialization intent was undeclared. The analyzer was right: Text
and Numeric are genuine designer state, but Number and Number64 are derived
views over Text, and the designer had been emitting meaningless
"Number = 0" / "Number64 = 0" lines into generated code for years. Intent
is now declared per property. Existing generated lines still compile, so
this changes only what the designer writes from here on.
* System.DirectoryServices is now part of the Windows Desktop shared
framework, so the explicit PackageReference was redundant (NU1510). It is
used by ActiveDirectoryService.cs and still resolves; the package is gone
and the SBOM is one entry shorter.
Packages taken to current: System.Management and
System.ServiceProcess.ServiceController 10.0.10 -> 10.0.11 in both
ControlPanel and DBSetup. WPF-UI 4.3.0, LiveChartsCore 2.0.5 and QRCoder
1.8.0 were already latest. The regression suite's packages.config is
deliberately untouched in this commit - it is the harness that validates
everything else, and bumping it belongs in its own change.
One thing deliberately NOT changed: MinVersion stays at 10.0.14393. The
comment claimed that build was the floor of the .NET 8 runtime, so the
obvious move was to raise it for .NET 10 - but .NET 10 still supports
Windows 10 1607 and Windows Server 2012, so raising it would have locked
out supported configurations for no reason.
Verification
* Both solutions build with 0 warnings, 0 errors.
* ControlPanel.Tests: 45/45 pass on net10.0.
* The published Control Panel starts and stays up - a WPF app can build
clean and still die at startup, so this was checked rather than assumed.
* The C++ server is untouched by this commit.
Copy file name to clipboardExpand all lines: README.md
+5-5Lines changed: 5 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -88,7 +88,7 @@ Technology
88
88
| Async I/O | Boost 1.91 (Asio) |
89
89
| Databases | MySQL, MariaDB, MS SQL Server, PostgreSQL 18 (libpq), and the embedded SQL CE for zero-configuration installs |
90
90
| MySQL/MariaDB client | MariaDB Connector/C, shipped as `libmysql.dll` with auth plugins — works with MySQL 8 `caching_sha2_password` and MariaDB `ed25519`/`gssapi` out of the box |
| Extensibility | COM/IDispatch API, plus a REST administration API |
93
93
| Schema | Database version 6005, upgradeable from every earlier hMailServer release |
94
94
@@ -97,12 +97,12 @@ Technology
97
97
Administration
98
98
==============
99
99
100
-
**hMailServer Control Panel** (`hMailCP.exe`) is the bundled administration GUI: a .NET 8 WPF application that talks to the server purely through the COM API. It covers domains, accounts, aliases, distribution lists, routes, rules, IP ranges, TCP/IP ports and SSL bindings, server settings, the live dashboard, the delivery queue, logs, status, backup, SSL certificates, scripts, Sieve scripts and public folders.
100
+
**hMailServer Control Panel** (`hMailCP.exe`) is the bundled administration GUI: a .NET 10 WPF application that talks to the server purely through the COM API. It covers domains, accounts, aliases, distribution lists, routes, rules, IP ranges, TCP/IP ports and SSL bindings, server settings, the live dashboard, the delivery queue, logs, status, backup, SSL certificates, scripts, Sieve scripts and public folders.
101
101
102
102
***Ctrl+K** searches every setting by label or INI key — type `delete logs`, `log level` or `LogDeleteDays` and it takes you to the page that owns it.
103
103
***Active Directory pickers**: a read-only browser lists the forest's domains and searches their users, to link an account to an AD user or bulk-import addresses into a distribution list.
104
104
* Optional TOTP two-factor authentication on logon.
105
-
* Requires the .NET 8 Desktop Runtime, which the installer bundles and installs silently when missing.
105
+
* Requires the .NET 10 Desktop Runtime, which the installer bundles and installs silently when missing.
106
106
107
107
**REST administration API** for domains, accounts, the delivery queue, server status and TLSA records, with authenticated access and bounded request handling (a size cap and a receive deadline, so a slow or oversized request cannot occupy a worker).
108
108
@@ -230,11 +230,11 @@ Alternatively, build from Visual Studio (started with _Run as Administrator_) or
230
230
1. Download the source code from this Git repository.
231
231
2. Compile the solution hmailserver\source\Server\hMailServer\hMailServer.sln.
232
232
This will build the hMailServer server-part (hMailServer.exe)
233
-
3. Build and publish the .NET 8 setup tools with build\build-tools.ps1 (or
233
+
3. Build and publish the .NET 10 setup tools with build\build-tools.ps1 (or
234
234
"dotnet build" on hmailserver\source\Tools\hMailServer Tools.sln).
235
235
This covers DB Setup, DB Setup Quick, DB Updater, the Data Directory
236
236
Synchronizer and the Import Tool.
237
-
The Control Panel is a separate .NET 8 solution, hmailserver\source\Tools\ControlPanel.sln.
237
+
The Control Panel is a separate .NET 10 solution, hmailserver\source\Tools\ControlPanel.sln.
Three things stand out and are worth naming rather than leaving to be inferred.
71
71
**Storage and the administration surface are the best-covered areas**, and the
@@ -84,7 +84,7 @@ previous version of this roadmap. Ordered by when they bite.
84
84
85
85
|| Date | Item | What happens |
86
86
|:-:|---|---|---|
87
-
|⬜|**10 Nov 2026**|**.NET 8 end of support**|The Control Panel and all six command-line tools target .NET 8. .NET 9 dies the same day, so the only target is **.NET 10 LTS** (EOL 14 Nov 2028). After this date the installer ships an unsupported runtime that will show up as an EOL component in our own SBOM, and a runtime CVE becomes unpatchable. **This is the hardest date on the board.**|
87
+
|✅|~~10 Nov 2026~~|**.NET 8 end of support — done, 12 Aug 2026**|Migrated to **.NET 10 LTS** (EOL 14 Nov 2028) with three months to spare. All nine projects retargeted to `net10.0-windows`, SDK pinned in `global.json` (`rollForward: latestFeature`, so a newer SDK on a build machine cannot silently change the toolchain), the bundled Desktop Runtime and the installer's version probe moved to 10.x, and packages taken to current. Everything builds with **0 warnings** and the Control Panel starts clean.|
88
88
| ⬜ |**End Dec 2026**|**Microsoft 365 turns off Basic auth for SMTP AUTH**| The outbound client offers exactly one mechanism — `AUTH LOGIN`. Anyone relaying through `smtp.office365.com` stops working. Needs a token cache plus XOAUTH2 encoding; note Exchange Online implements **XOAUTH2 only**, not RFC 7628 OAUTHBEARER. Collecting *from* M365 over POP/IMAP has already been broken since 2022. |
89
89
| ⬜ |**9 Dec 2026**|**EU Product Liability Directive (2024/2853)**| Software is unambiguously a "product"; a product can be defective *because of a vulnerability or a failure to ship security updates*, and liability **cannot be disclaimed by licence** — AGPLv3's warranty disclaimer does not help. FOSS supplied outside a commercial activity is exempt. Documentation, not code, but it should drive a business decision. |
90
90
| ⬜ |**12 Jan 2027**|**Windows Server 2016 end of support**| The moment to declare a supported floor. Recommendation: **Server 2019 / Windows 10 21H2**, which costs zero code — Server 2019 is still `_WIN32_WINNT=0x0A00`. Do not raise the macro past that; self-hosted mail skews old and Server 2019 has support into 2029. |
@@ -983,7 +983,7 @@ Future-proofing: platform and supply chain
983
983
984
984
|| Item | Detail |
985
985
|:-:|---|---|
986
-
|⬜|**Migrate to .NET 10 LTS**|See the dated table — 10 Nov 2026, and the hardest deadline here. |
986
+
|✅|**Migrate to .NET 10 LTS**|Done 12 Aug 2026, ahead of the 10 Nov 2026 deadline. Nine projects to `net10.0-windows`; SDK 10.0.303 pinned in `global.json`; bundled Desktop Runtime, the installer's `Microsoft.WindowsDesktop.App\10.*` probe, the runtime-fetch script, the screenshot script and the docs all moved together. Two real findings on the way: .NET 9 added the **WFO1000** WinForms analyzer, which (correctly) rejected four properties on `ucText` whose designer-serialization intent was undeclared — the designer had been emitting meaningless `Number = 0` lines for years; and `System.DirectoryServices` is now in the Windows Desktop shared framework, so that `PackageReference` was redundant and is gone. **`MinVersion` stays at 10.0.14393** — .NET 10 still supports Windows 10 1607 and Server 2012, which was worth checking rather than assuming. |
987
987
| ⬜ |**Decide the OpenSSL branch**| 4.0.x is not LTS and dies 14 May 2027. Decide by Q1 2027 whether to follow to the next LTS or move back to 3.5. |
988
988
| ⬜ |**Declare a supported Windows floor**| Server 2019 / Windows 10 21H2, effective with the first release after 12 Jan 2027. Zero code cost — Server 2019 is still `_WIN32_WINNT=0x0A00`, and that macro should *not* be raised. |
989
989
| ⬜ |**Artifact signing**| SBOMs are already attached to every release in both SPDX and CycloneDX. The gap is signing: Authenticode on the installer and binaries, and ideally Sigstore for the release artefacts. This is the supply-chain item that is actually missing, and the CRA makes update integrity a formal requirement if scope ever changes. |
"//": "Pins the .NET SDK so builds are reproducible and installing a newer SDK on a build machine cannot silently change the toolchain. rollForward latestFeature accepts 10.0.3xx and later within .NET 10, but never rolls to .NET 11 - that has to be a deliberate edit here, alongside the TargetFramework values and the runtime the installer bundles.",
0 commit comments