C#WinScard.SCardListReaders应仅列出已连接的读卡器(但它列出了所有以前安装的读卡器名称,但现在未连接)

C#WinScard.SCardListReaders应仅列出已连接的读卡器(但它列出了所有以前安装的读卡器名称,但现在未连接),c#,winscard,C#,Winscard,请检查我下面的C代码。我正在尝试获取已连接到我的计算机的智能卡读卡器列表。但此函数将返回过去连接的所有智能卡读卡器名称(我的意思是现在未连接)。我只想要活动(当前)连接的读卡器名称列表。我不明白问题在哪里 我尝试了一个用C编写和编译的exe。它只显示连接的读卡器。我比较了代码,但没有发现差异。请帮我找到一个解决办法 public static int GetPCSCReaders(out List<string> smartCardReaders, out string errMsg

请检查我下面的C代码。我正在尝试获取已连接到我的计算机的智能卡读卡器列表。但此函数将返回过去连接的所有智能卡读卡器名称(我的意思是现在未连接)。我只想要活动(当前)连接的读卡器名称列表。我不明白问题在哪里

我尝试了一个用C编写和编译的exe。它只显示连接的读卡器。我比较了代码,但没有发现差异。请帮我找到一个解决办法

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;
}
public static int GetPCSCReaders(输出列表智能卡读卡器,输出字符串errMsg)
{
errMsg=string.Empty;
字节[]readersList=null;
smartCardReaders=新列表();
尝试
{
int-hContext=0;
int-ret=scardesttablishContext(WinSCard.SCARD\u SCOPE\u USER,0,0,ref-hContext);
如果(ret!=0)
{
errMsg=“WinSCard GetPCSCReader:EstablishContext错误:”+ret.ToString();
返回ret;
}
int字节=0;
ret=WinSCard.SCardListReaders(hContext,null,null,ref byteCnt);
如果(ret!=伤痕累累的成功)
{
errMsg=“WinSCard GetPCSCReader:ListReaders错误:”+ret.ToString();
返回ret;
}
readersList=新字节[byteCnt];
ret=WinSCard.SCardListReaders(hContext,null,readersList,ref byteCnt);
如果(ret!=伤痕累累的成功)
{
errMsg=“WinSCard GetPCSCReader:ListReaders错误:”+ret.ToString();
返回ret;
}
int indx=0;
string readerName=string.Empty;
int i=0;
while(readersList[indx]!=0)
{
while(readersList[indx]!=0)
{
readerName=readerName+(char)readerList[indx++];
}
smartCardReaders.Add(readerName);
i++;
readerName=“”;
indx++;
}
}
捕获(例外情况除外)
{
errMsg=例如消息;
}
最后
{
readersList=null;
}
返回0;
}

如果没有智能卡读卡器,很难回答这个问题,尽管我是在3个月前用这些代码开发的

我以前的代码基于以下内容:

它不能完美地工作,你必须自己检测bug。但这确实有帮助

在不同的windows平台上有不同的解决方案

  • 窗口8.1+:
  • 窗口10:
  • Windows 7+:
  • 如果你在C++中遇到C语言的问题,你可以在这里找到所有的函数: 只需从左上角搜索函数。

    我浏览了这一部分,在那一页中,有一个提示和技巧提到,“如果您在hContext参数设置为null的情况下调用SCardListReaders,您将获得已安装读卡器的列表(而不是插入的读卡器!)”。因此,在我的代码中,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;
    }
    
    public static int GetPCSCReaders(输出列表智能卡读卡器,输出字符串errMsg)
    {
    errMsg=string.Empty;
    smartCardReaders=新列表();
    IntPtr-hContext;
    尝试
    {
    int-ret=scardesttablishContext(SCARD\u SCOPE\u USER、IntPtr.Zero、IntPtr.Zero、out-hContext);
    如果(ret!=伤痕累累的成功)
    {
    errMsg=“WinSCard GetPCSCReader:EstablishContext错误:”+ret.ToString();
    返回ret;
    }
    字节[]readersList=null;
    uint字节数=0;
    ret=SCardListReaders(hContext、null、null、ref字节);
    如果(ret!=伤痕累累的成功)
    {
    errMsg=“WinSCard GetPCSCReader:ListReaders错误:”+ret.ToString();
    返回ret;
    }
    readersList=新字节[byteCnt];
    ret=SCardListReaders(hContext,null,ReaderList,ref byteCnt);
    如果(ret!=伤痕累累的成功)
    {
    errMsg=“WinSCard GetPCSCReader:ListReaders错误:”+ret.ToString();
    返回ret;
    }
    int indx=0;
    string readerName=string.Empty;
    int i=0;
    while(readersList[indx]!=0)
    {
    while(readersList[indx]!=0)
    {
    readerName=readerName+(char)readerList[indx++];
    }
    smartCardReaders.Add(readerName);
    i++;
    readerName=“”;
    indx++;
    }
    }
    捕获(例外情况除外)
    {
    errMsg=例如消息;
    }
    最后
    {
    }
    返回0;
    }
    
    感谢您花时间分享这些有用的链接。我浏览了这个链接(),其中有一个提示和技巧提到,“如果您在hContext参数设置为null的情况下调用SCardListReaders,您将获得已安装的读卡器列表(而不是插入的读卡器!)”。因此,在我的代码中,hContext变量是int,我将其更改为IntPtr,它使我只列出连接的读卡器。解决了@AnanthaPrasad将其标记为“不可接受”答案,扣15分。我应该删除我的答案吗?因为你的答案导致了我已经评论过的解决方案。您的答案是正确的,并且被接受。请注意:我在x64中编译时遇到了这个问题,但在x86中没有。