我正在尝试检测卡片何时插入读卡器。 如果我像这样进行讨厌的轮询循环:
public struct SCARD_READERSTATE
{
[MarshalAs(UnmanagedType.LPWStr)]
public string szReader;
public byte[] pvUserData;
public byte[] rgbAtr;
public uint dwCurrentState;
public uint dwEventState;
public uint cbAtr;
}
byte[] atr = null;
SCARD_READERSTATE[] rs = new SCARD_READERSTATE[1];
rs[0].szReader = readersList[0];
rs[0].dwCurrentState = SCARD_STATE_UNAWARE;
rs[0].dwEventState = SCARD_STATE_PRESENT;
int hctx = hContext.ToInt32();
var cardResult = SCardGetStatusChange(hctx, 100, rs, 1);
if (cardResult == 0 && rs[0].cbAtr > 0 && rs[0].rgbAtr != null)
{
atr = new byte[rs[0].cbAtr];
Array.Copy(rs[0].rgbAtr, atr, rs[0].cbAtr);
}
while ( (rs[0].dwCurrentState & SCARD_STATE_PRESENT) == 0)
{
rs = new SCARD_READERSTATE[1];
rs[0].szReader = readersList[0];
//rs[0].dwCurrentState = SCARD_STATE_PRESENT;
//rs[0].dwEventState = SCARD_STATE_PRESENT;
SCardGetStatusChange(hctx, 100000000, rs, 1);
System.Threading.Thread.Sleep(1000);
}
它可以工作,但它有一个令人讨厌的线程休眠。理想情况下,我想在后台线程上对 SCardGetStatusChange 进行阻塞调用,然后显示事件。
显然,通过将 szReader 设置为值“\\?PnP?\Notification”,只要结构中的其他所有内容都为 0,它就会阻塞。
我已经将代码更改为
rs[0].szReader = "\\\\?PnP?\\Notification";
rs[0].cbAtr = 0;
rs[0].dwCurrentState = 0;
rs[0].dwEventState = 0;
rs[0].pvUserData = new byte[0];
rs[0].rgbAtr = new byte0];
SCardGetStatusChange(hctx, 100000000, rs, 1);
但它只是立即返回成功结果。那里的任何 pInvoke 大师都可以看出问题所在吗?
最佳答案
在您的示例中,第二次调用
SCardGetStatusChange
如果您将 dwEventState 复制到 dwCurrentState 然后重置 dwEventState,应该会阻塞,因此不需要 sleep 。“\\?PnP?\Notification”结构是在连接新智能卡读卡器时通知您,而不是在插入卡时通知您。 From the MSDN page on SCardGetStatusChange :
To be notified of the arrival of a new smart card reader, set the szReader member of a SCARD_READERSTATE structure to "\\?PnP?\Notification", and set all of the other members of that structure to zero.
当使用“\\?PnP?\Notification”结构时:
pvUserData
和rgbAttr
字段应设置为null
- 一个
new byte[0]
是指向零长度数组的有效指针,但 API 在这里需要的是空指针或零值)
- 一个
- dwCurrentState 的高 16 位应包含当前读取器计数
- 即
rs[0].dwCurrentState = (readerCount << 16);
- MSDN 页面目前在这一点上不准确。
- 即
关于c# - 使用 SCardGetStatusChange 通知卡插入/移除而不轮询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16370909/