C # WinScard.SCardListReaders должен перечислять только подключенные читатели (но он перечисляет все ранее установленные имена читателей, которые сейчас не подключены) - PullRequest
0 голосов
/ 23 октября 2018

Пожалуйста, пройдите мой код 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;
}

Ответы [ 2 ]

0 голосов
/ 24 октября 2018

Я прошел по этой ссылке , на этой странице есть упоминание Советов и Уловок: «Если вы вызовете SCardListReaders с параметром hContext, установленным в ноль, вы получите список установленных читателей.(не подключенные!) ".Согласно этому, в моем коде у меня была переменная 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;
}
0 голосов
/ 23 октября 2018

Трудно ответить на вопрос без считывателя смарт-карт, хотя я разработал этот код всего 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

Окно 10:

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

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

Windows 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 просто найдите функцию сверху слева.

...