C#SCardGetStatusChange()检查智能卡状态
我想检测智能卡的状态,查看是否插入或拔出了智能卡C#SCardGetStatusChange()检查智能卡状态,c#,smartcard,C#,Smartcard,我想检测智能卡的状态,查看是否插入或拔出了智能卡 为此,我使用智能卡读取代码 我发现可以检测到SCardGetStatusChange功能,但不知道如何使用。 这是我的添加代码 [DllImport("winscard.dll")] public static extern int SCardGetStatusChange(int hContext,uint dwTimeout,[In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamInd
为此,我使用智能卡读取代码 我发现可以检测到
SCardGetStatusChange
功能,但不知道如何使用。
这是我的添加代码
[DllImport("winscard.dll")]
public static extern int SCardGetStatusChange(int hContext,uint dwTimeout,[In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=3)]SCARD_READERSTATE[] rgReaderState,uint cReaders);
public struct SCARD_READERSTATE
{
[MarshalAs(UnmanagedType.LPTStr)]
public string szReader;
public IntPtr pvUserData;
public uint dwCurrentState;
public uint dwEventState;
public uint cbAtr;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 36)]
public byte[] rgbAtr;
}
SCARD_READERSTATE[] rs = new SCARD_READERSTATE[1];
rs[0].szReader = ReaderList;
rs[0].dwCurrentState = SCARD_STATE_UNAWARE;
int result = SCardGetStatusChange(ContextHandle, 1000, rs, 2);
但是结果总是一样的,我不知道什么是错误的参数。这里有一个程序,可以做你喜欢的事情,你可以根据你的需要修改代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Text;
namespace SimpleSmartCardTester
{
static class Program
{
public static class SmartCardScope
{
public static readonly Int32 User = 0;
public static readonly Int32 Terminal = 1;
public static readonly Int32 System = 2;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct SmartCardReaderState
{
public string cardReaderString;
public IntPtr userDataPointer;
public UInt32 currentState;
public UInt32 eventState;
public UInt32 atrLength;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 36)]
public byte[] ATR;
}
public static class SmartCardState
{
public static readonly UInt32 Unaware = 0x00000000;
public static readonly UInt32 Ignore = 0x00000001;
public static readonly UInt32 Changed = 0x00000002;
public static readonly UInt32 Unknown = 0x00000004;
public static readonly UInt32 Unavailable = 0x00000008;
public static readonly UInt32 Empty = 0x00000010;
public static readonly UInt32 Present = 0x00000020;
public static readonly UInt32 Atrmatch = 0x00000040;
public static readonly UInt32 Exclusive = 0x00000080;
public static readonly UInt32 Inuse = 0x00000100;
public static readonly UInt32 Mute = 0x00000200;
public static readonly UInt32 Unpowered = 0x00000400;
}
public const int SCARD_S_SUCCESS = 0;
[DllImport("winscard.dll")]
internal static extern int SCardEstablishContext(Int32 dwScope, IntPtr pReserved1, IntPtr pReserved2, out Int32 hContext);
[DllImport("winscard.dll", EntryPoint = "SCardListReadersA", CharSet = CharSet.Ansi)]
internal static extern int SCardListReaders(Int32 hContext, byte[] cardReaderGroups, byte[] readersBuffer, out UInt32 readersBufferLength);
[DllImport("winscard.dll")]
internal static extern int SCardGetStatusChange(Int32 hContext, UInt32 timeoutMilliseconds, [In, Out] SmartCardReaderState[] readerStates, Int32 readerCount);
private static List<string> ParseReaderBuffer(byte[] buffer)
{
var str = Encoding.ASCII.GetString(buffer);
if (string.IsNullOrEmpty(str)) return new List<string>();
return new List<string>(str.Split(new char[] { '\0' }, StringSplitOptions.RemoveEmptyEntries));
}
private static bool CheckIfFlagsSet(UInt32 mask, params UInt32[] flagList)
{
foreach (UInt32 flag in flagList)
{
if (IsFlagSet(mask, flag)) return true;
}
return false;
}
private static bool IsFlagSet(UInt32 mask, UInt32 flag)
{
return ((flag & mask) > 0);
}
static void Main()
{
int context = 0;
Console.WriteLine("Checking card readers...)");
var result = SCardEstablishContext(SmartCardScope.User, IntPtr.Zero, IntPtr.Zero, out context);
if (result != SCARD_S_SUCCESS) throw new Exception("Smart card error: " + result.ToString());
uint bufferLength = 10000;
byte[] readerBuffer = new byte[bufferLength];
result = SCardListReaders(context, null, readerBuffer, out bufferLength);
if (result != SCARD_S_SUCCESS) throw new Exception("Smart card error: " + result.ToString());
var readers = ParseReaderBuffer(readerBuffer);
Console.WriteLine("{0} Card Reader(s)", readers.Count);
if (readers.Any())
{
var readerStates = readers.Select(cardReaderName => new SmartCardReaderState() { cardReaderString = cardReaderName }).ToArray();
result = SCardGetStatusChange(context, 1000, readerStates, readerStates.Length);
if (result != SCARD_S_SUCCESS) throw new Exception("Smart card error: " + result.ToString());
readerStates.ToList().ForEach(readerState => Console.WriteLine("Reader: {0}, State: {1}", readerState.cardReaderString,
CheckIfFlagsSet(readerState.eventState, SmartCardState.Present, SmartCardState.Atrmatch) ? "Card Present" : "Card Absent"));
}
Console.ReadLine();
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用System.Threading.Tasks;
使用System.Windows.Forms;
使用System.Runtime.InteropServices;
使用系统文本;
命名空间SimpleSmartCardTester
{
静态类程序
{
公共静态类SmartCardScope
{
公共静态只读Int32用户=0;
公共静态只读Int32终端=1;
公共静态只读Int32系统=2;
}
[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Ansi)]
公共结构SmartCardReaderState
{
公共字符串读卡器字符串;
公共IntPtr userDataPointer;
公共UInt32当前状态;
公共UInt32事件状态;
公共UInt32 ATR长度;
[Marshallas(UnmanagedType.ByValArray,SizeConst=36)]
公共字节[]ATR;
}
公共静态类SmartCardState
{
公共静态只读UInt32=0x00000000;
公共静态只读UInt32 Ignore=0x00000001;
公共静态只读UInt32已更改=0x00000002;
公共静态只读UInt32未知=0x00000004;
公共静态只读UInt32不可用=0x00000008;
公共静态只读UInt32 Empty=0x00000010;
存在公共静态只读UInt32=0x00000020;
公共静态只读UInt32 Atrmatch=0x00000040;
公共静态只读UInt32独占=0x00000080;
公共静态只读UInt32 Inuse=0x00000100;
公共静态只读UInt32静音=0x00000200;
公共静态只读UInt32无电源=0x00000400;
}
公共建筑的成功率=0;
[DllImport(“winscard.dll”)]
内部静态外部int ScardestStablishContext(Int32 dwScope、IntPtr pReserved1、IntPtr pReserved2、out Int32 hContext);
[DllImport(“winscard.dll”,EntryPoint=“SCardListReadersA”,CharSet=CharSet.Ansi)]
内部静态外部int SCardListReaders(Int32 hContext,字节[]CardReaderGroup,字节[]readersBuffer,out UInt32 readersBufferLength);
[DllImport(“winscard.dll”)]
内部静态外部int SCardGetStatusChange(Int32 hContext,UInt32 timeout毫秒,[In,Out]智能卡读卡器状态[]读卡器状态,Int32读卡器计数);
专用静态列表ParseReaderBuffer(字节[]缓冲区)
{
var str=Encoding.ASCII.GetString(缓冲区);
if(string.IsNullOrEmpty(str))返回新列表();
返回新列表(str.Split(新字符[]{'\0'},StringSplitOptions.RemoveEmptyEntries));
}
专用静态布尔校验集(UInt32掩码,参数UInt32[]标志列表)
{
foreach(旗标列表中的UInt32旗标)
{
if(IsFlagSet(mask,flag))返回true;
}
返回false;
}
专用静态bool IsFlagSet(UInt32掩码,UInt32标志)
{
返回((标志和掩码)>0);
}
静态void Main()
{
int-context=0;
控制台。WriteLine(“检查读卡器…”);
var result=scardesttablishContext(SmartCardScope.User、IntPtr.Zero、IntPtr.Zero、out context);
如果(result!=SCARD_S_SUCCESS)抛出新异常(“智能卡错误:+result.ToString());
uint缓冲长度=10000;
字节[]readerBuffer=新字节[bufferLength];
结果=SCardListReaders(上下文,null,readerBuffer,out bufferLength);
如果(result!=SCARD_S_SUCCESS)抛出新异常(“智能卡错误:+result.ToString());
var readers=ParseReaderBuffer(readerBuffer);
Console.WriteLine({0}读卡器),readers.Count);
if(readers.Any())
{
var readerStates=readers.Select(cardReaderName=>new SmartCardReaderState(){cardReaderString=cardReaderName}).ToArray();
结果=SCardGetStatusChange(上下文,1000,readerStates,readerStates.Length);
如果(result!=SCARD_S_SUCCESS)抛出新异常(“智能卡错误:+result.ToString());
readerStates.ToList().ForEach(readerState=>Console.WriteLine(“Reader:{0},State:{1}”,readerState.cardReaderString,
检查标签集(readerState.eventState、SmartCardState.Present、SmartCardState.Atrmatch)?“卡片存在”:“卡片不存在”);
}
Console.ReadLine();
}
}
}
始终访问www.pinvoke.net。请看:通过进一步搜索,是否有帮助?@SivaGopal我使用了您的第二个链接,但我不知道如何调用>>私有静态字节[]atr(int-hContext,string reader)@SivaGopal谢谢,我尝试了成功。我怎样才能给你正确的答案?