我正在开发使用 Mifare Classic 1K 卡和 HID Omnikey 5421(5321 的继任者)的应用程序。我使用线程来检测卡移除/插入。Delphi代码(线程方法):
function CardWatcherThread(PContext: Pointer): integer;
var
RetVar : cardinal;
RContext : cardinal;
RStates : array[0..0] of SCARD_READERSTATEA;
begin
try
RContext := Cardinal(PContext^);
FillChar(RStates,SizeOf(RStates),#0);
RStates[0].szReader := SelectedReader;
RStates[0].pvUserData := nil;
RStates[0].dwCurrentState := SCARD_STATE_UNAWARE;
while ReaderOpen and (not Application.Terminated) do begin
RetVar := SCardGetStatusChange(RContext, MAX_WAIT_TIME_SCARDSTATUSCHANGE, @RStates, 1);
RStates[0].dwCurrentState := RStates[0].dwEventState;
ActReaderState := RStates[0].dwEventState;
// Avoid sedning error about timemout if MAX_WAIT_TIME_SCARDSTATUSCHANGE is not infinite
if (RetVar <> SCARD_E_TIMEOUT) or (MAX_WAIT_TIME_SCARDSTATUSCHANGE = -1) then begin
SendMessage(NotifyHandle, WM_CARDSTATE, RetVar, 0);
end;
end;
finally
Result := 0;
end;
end;
我正在使用 SendMessage 通知我的智能卡类我检测到正确的状态。当我检测到卡插入时,我也会自动连接并从智能卡读取数据。
我的应用程序在大多数情况下都可以正常工作,但有时例如在 10000 次卡插入中,我会从SCardGetStatusChange
. 当这种情况发生时,SCardGetStatusChange 开始一直只产生SCARD_F_INTERNAL_ERROR。当我检测到这种情况时,我尝试结束线程SCardCancel
并SCardReleaseContext
建立新上下文并使用这个新上下文创建新的观察者线程,但这没有帮助,因为 SCardGetStatusChange 继续返回SCARD_F_INTERNAL_ERROR。只有当我关闭应用程序并再次运行时,问题才会消失。它对我来说是随机发生的,我无法使用某些已知场景重现它。在 PC 中可以有更多的读者,但我只建立与 Omnikey 5421 的连接。
有人遇到过这个问题吗?