Release v1.0.3: Enhanced NDEF reading and UX improvements

Major Improvements:
- Implement exclusive card access with retry logic and exponential backoff
- Fix Type 4 NDEF length parsing (now correctly reads NTAG424 and similar chips)
- Add enhanced card type detection (Type 2 vs Type 4)
- Implement chunked reading for large NDEF messages
- Add proper TLV parsing for Type 2 tags

Bug Fixes:
- Fix WPF window lifecycle issue (visual tree error on reopen)
- Fix NDEF length parsing incorrectly detecting extended format
- Correct data offset for Type 4 tag reading

New Features:
- Multi-line log selection and copy to clipboard
- Context menu with Copy Selected Lines, Copy All, Select All
- Runtime version roll-forward support (.NET 8.0.x compatibility)

Technical Details:
- Type 4 tags now use correct 2-byte NLEN field per NFC Forum spec
- Removed incorrect 3-byte extended length detection
- Window now hides instead of closing for proper tray app behavior
- Connection attempts exclusive access first, falls back to shared mode
- Status timeout increased from 0ms to 1000ms for better card detection
This commit is contained in:
2025-11-18 22:20:13 -08:00
parent 308966da36
commit a1d03fec2a
6 changed files with 585 additions and 31 deletions

View File

@@ -24,6 +24,7 @@ public partial class App : Application
private ActionService? _actionService;
private LogService? _logService;
private MainViewModel? _viewModel;
private System.ComponentModel.CancelEventHandler? _windowClosingHandler;
public App()
{
@@ -121,16 +122,44 @@ public partial class App : Application
private void ShowMainWindow()
{
if (_mainWindow != null)
// If window was closed, recreate it
if (_mainWindow == null || !_mainWindow.IsLoaded)
{
_mainWindow.Show();
_mainWindow.WindowState = WindowState.Normal;
_mainWindow.Activate();
if (_viewModel == null) return;
_mainWindow = new MainWindow(_viewModel);
// Handle window closing - hide instead of close
_windowClosingHandler = (s, e) =>
{
e.Cancel = true;
if (_mainWindow != null)
{
_mainWindow.Hide();
}
};
_mainWindow.Closing += _windowClosingHandler;
}
_mainWindow.Show();
_mainWindow.WindowState = WindowState.Normal;
_mainWindow.Activate();
}
private void ExitApplication()
{
// Properly close the main window if it exists
if (_mainWindow != null)
{
// Remove the cancel handler so the window can actually close
if (_windowClosingHandler != null)
{
_mainWindow.Closing -= _windowClosingHandler;
}
_mainWindow.Close();
}
_notifyIcon?.Dispose();
_customIcon?.Dispose();
_cardReaderService?.Dispose();