WinUI3 C++/winrt packaged SmartCardReader application does not terminate process in a timely manner
Describe the bug
An application uses winrt::Windows::Devices::Enumeration::DeviceWatcher and creates a winrt::Windows::Devices::SmartCards::SmartCardReader instance by calling
co_await winrt::Windows::Devices::Enumeration::DeviceInformation::FindAllAsync(SmartCardReader::GetDeviceSelector())
and then create a reader instance with co_await SmartCardReader::FromIdAsync(device.Id()) from the collection above.
Start the application and connect the smart card reader. Close the application. Open TaskMonitor and observe that application process is still running, Stack trace of that process shows this:
> ntdll.dll!NtWaitForSingleObject() Unknown
KERNELBASE.dll!WaitForSingleObjectEx() Unknown
Windows.Devices.SmartCards.dll!Windows::Devices::SmartCards::SmartCardReaderEventManager::WaitForEvent(void *,unsigned long) Unknown
Windows.Devices.SmartCards.dll!Windows::Devices::SmartCards::SmartCardReaderEventManager::InternalDeinitialize(void) Unknown
Windows.Devices.SmartCards.dll!ComErrorContract<<lambda_da5d591f47daddf166a5d7c13fa896d9>>() Unknown
Windows.Devices.SmartCards.dll!Windows::Devices::SmartCards::SmartCardReaderEventManager::Deinitialize(void) Unknown
Windows.Devices.SmartCards.dll!Windows::Devices::SmartCards::SmartCardReaderEventManager::~SmartCardReaderEventManager(void) Unknown
ucrtbase.dll!<lambda>(void)() Unknown
ucrtbase.dll!__crt_seh_guarded_call<int>::operator()<<lambda_7777bce6b2f8c936911f934f8298dc43>,<lambda>(void) &,<lambda>(void)>() Unknown
ucrtbase.dll!_execute_onexit_table() Unknown
ucrtbase.dll!__crt_state_management::wrapped_invoke<int (*)(struct _onexit_table_t *),struct _onexit_table_t *,int>(int (*)(struct _onexit_table_t *),struct _onexit_table_t *) Unknown
Windows.Devices.SmartCards.dll!dllmain_crt_process_detach() Unknown
Windows.Devices.SmartCards.dll!dllmain_dispatch() Unknown
ntdll.dll!LdrpCallInitRoutine() Unknown
ntdll.dll!LdrShutdownProcess() Unknown
ntdll.dll!RtlExitUserProcess() Unknown
kernel32.dll!ExitProcessImplementation() Unknown
ucrtbased.dll!exit_or_terminate_process(const unsigned int return_code) Line 138 C++
ucrtbased.dll!common_exit(const int return_code, const _crt_exit_cleanup_mode cleanup_mode, const _crt_exit_return_mode return_mode) Line 274 C++
ucrtbased.dll!exit(int return_code) Line 288 C++
winrtsmartcardtest.exe!00007ff7ee15021b() Unknown
winrtsmartcardtest.exe!00007ff7ee1500be() Unknown
winrtsmartcardtest.exe!00007ff7ee1503ae() Unknown
kernel32.dll!BaseThreadInitThunk() Unknown
ntdll.dll!RtlUserThreadStart() Unknown
After a while the process ends. If a call to winrt::Windows::Devices::Enumeration::DeviceInformation::FindAllAsync is commented out, the application process ends immediately when the application main window is closed. Application uses deviceWatcher.Stop() call during its cleanup/shutdown routine.
This process exit delay prevents single-app-instance application type from running again when a previous instance has just closed.
Steps to reproduce the bug
Use any of the samples from https://github.com/microsoft/Windows-universal-samples/tree/main/Samples/DeviceEnumerationAndPairing/cppwinrt and add a call to winrt::Windows::Devices::Enumeration::DeviceWatcher and winrt::Windows::Devices::Enumeration::DeviceInformation::FindAllAsync(SmartCardReader::GetDeviceSelector()).
Expected behavior
An app should exit the same way with or without card reader attached.
Screenshots
No response
NuGet package version
None
Packaging type
Packaged (MSIX)
Windows version
Windows 11 version 22H2 (22621, 2022 Update)
IDE
Other
Additional context
No response
Does this only appear in when using the WinUI 3 library, or can you get the same thing to happen if you use the smart card reader in a Windows API application?
A simple test application using SCardEstablishContext, SCardListReaders, SCardConnect and SCardReleaseContext does not have a similar problem. When the application exits, there is no remaining process running. On the other hand, it is using WinSCard.dll and not Windows.Devices.SmartCards.dll which is pulled in when using WinUI3/WinRT API for smartcards.
What about using the device and smart card WinRT API in a Windows API application?
The same problem - it is calling into Windows.Devices.SmartCards.dll which hangs in WaitForSingleObjectEx during application exit.
I'm seeing this in my C# .net9.0-windows10.0.19041.0 Avalonia application. Is there any plans to fix this?
/external
Man, so I guess this won't be fixed?... any suggestions on where we should go to try to get a fix?
@BobbyCannon
- https://github.com/microsoft/WindowsAppSDK/discussions/1876.
I fixed it by calling into winscard.dll directly (LoadLibrary) and not using Windows.Devices.SmartCards.dll at all.