3

请浏览我下面的 C# 代码。我正在尝试获取现在连接到我的计算机的智能卡读卡器列表。但是这个函数会返回过去连接的所有智能卡读卡器名称(我的意思是现在没有连接)。我只想要活动(当前)连接的读者名称列表。我无法理解问题出在哪里。

我尝试了这个网站上的一个 exe,它是用 C 编写和编译的。它只显示连接的读者。我比较了代码,但我发现没有区别。请帮助找到解决方法。

public static int GetPCSCReaders(out List<string> smartCardReaders, out string errMsg)
{
    errMsg = string.Empty;
    byte[] readersList = null;
    smartCardReaders = new List<string>();

    try
    {
        int hContext = 0;
        int ret = SCardEstablishContext(WinSCard.SCARD_SCOPE_USER, 0, 0, ref hContext);
        if (ret != 0)
        {
            errMsg = "WinSCard GetPCSCReader: EstablishContext Error: " + ret.ToString();
            return ret;
        }

        int byteCnt = 0;
        ret = WinSCard.SCardListReaders(hContext, null, null, ref byteCnt);
        if (ret != SCARD_S_SUCCESS)
        {
            errMsg = "WinSCard GetPCSCReader: ListReaders Error: " + ret.ToString();
            return ret;
        }

        readersList = new byte[byteCnt];
        ret = WinSCard.SCardListReaders(hContext, null, readersList, ref byteCnt);
        if (ret != SCARD_S_SUCCESS)
        {
            errMsg = "WinSCard GetPCSCReader: ListReaders Error: " + ret.ToString();
            return ret;
        }

        int indx = 0;
        string readerName = string.Empty;
        int i = 0;

        while (readersList[indx] != 0)
        {
            while (readersList[indx] != 0)
            {
                readerName = readerName + (char)readersList[indx++];
            }

            smartCardReaders.Add(readerName);
            i++;

            readerName = "";
            indx++;
        }

    }
    catch (Exception ex)
    {
        errMsg = ex.Message;
    }
    finally
    {
        readersList = null;
    }
    return 0;
}
4

2 回答 2

1

我浏览了这个链接,在那个页面中,有一个提示和技巧提到,“如果您调用 SCardListReaders 并将 hContext 参数设置为 null,您将获得已安装阅读器的列表(而不是插入的阅读器!)”。据此,在我的代码中,我将 hContext 变量设置为 int,我将其更改为 IntPtr,它让我只列出连接的阅读器。它已解决,现在我的代码更改为

public static int GetPCSCReaders(out List<string> smartCardReaders, out string errMsg)
{
    errMsg = string.Empty;
    smartCardReaders = new List<string>();
    IntPtr hContext;

    try
    {
        int ret = SCardEstablishContext(SCARD_SCOPE_USER, IntPtr.Zero, IntPtr.Zero, out hContext);
        if (ret != SCARD_S_SUCCESS)
        {
            errMsg = "WinSCard GetPCSCReader: EstablishContext Error: " + ret.ToString();
            return ret;
        }

        byte[] readersList = null;
        uint byteCnt = 0;
        ret = SCardListReaders(hContext, null, null, ref byteCnt);
        if (ret != SCARD_S_SUCCESS)
        {
            errMsg = "WinSCard GetPCSCReader: ListReaders Error: " + ret.ToString();
            return ret;
        }

        readersList = new byte[byteCnt];
        ret = SCardListReaders(hContext, null, readersList, ref byteCnt);
        if (ret != SCARD_S_SUCCESS)
        {
            errMsg = "WinSCard GetPCSCReader: ListReaders Error: " + ret.ToString();
            return ret;
        }

        int indx = 0;
        string readerName = string.Empty;
        int i = 0;

        while (readersList[indx] != 0)
        {
            while (readersList[indx] != 0)
            {
                readerName = readerName + (char)readersList[indx++];
            }

            smartCardReaders.Add(readerName);
            i++;

            readerName = "";
            indx++;
        }

    }
    catch (Exception ex)
    {
        errMsg = ex.Message;
    }
    finally
    {

    }
    return 0;
}
于 2018-10-24T12:00:56.013 回答
1

没有智能卡读卡器就很难回答这个问题,尽管我在 3 个月前开发了这些代码。

我之前的代码基于此: https ://github.com/nicbedford/CardBrowser/blob/master/PCSC/PCSCReader.cs

它不能完美运行,您必须自己检测错误。但它确实有帮助。

不同的windows平台有不同的解决方案。

  1. 窗口 8.1+:

https://code.msdn.microsoft.com/windowsapps/Smart-card-sample-c7d342e0#content

  1. 窗口 10:

https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/SmartCard

https://docs.microsoft.com/en-us/uwp/api/windows.devices.smartcards

  1. 视窗 7+:

https://github.com/nicbedford/CardBrowser/tree/master/PCSC

https://github.com/orouit/SmartcardFramework

https://github.com/danm-de/pcsc-sharp/tree/master/src/PCSC

如果您在将 C++ 转换为 C# 时遇到问题,您可以在此处找到所有函数: https ://www.pinvoke.net/default.aspx/winscard/SCardTransmit.html 只需从左上​​角搜索函数。

于 2018-10-23T20:33:32.923 回答