Sample code for 30+ languages & platforms
AutoIt

PC/SC Wait for Smart Card Status Change (Inserted, Removed from Reader, etc.)

See more SCard Examples

Demonstrates how to synchronously wait for a status change, such as for a smart card to be inserted into a reader, or removed from a reader.

Note: This functionality was introduced in Chilkat v9.5.0.87.

Chilkat AutoIt Downloads

AutoIt
Local $bSuccess = False

;  This example requires the Chilkat API to have been previously unlocked.
;  See Global Unlock Sample for sample code.

$oScard = ObjCreate("Chilkat.SCard")

;  First establish a context to the PC/SC Resource Manager
$bSuccess = $oScard.EstablishContext("user")
If ($bSuccess = False) Then
    ConsoleWrite($oScard.LastErrorText & @CRLF)
    Exit
EndIf

;  First we'll examine the state of all connected readers to see which have smartcards already inserted..
;  Get JSON containing information about the smartcards currently inserted into readers.
;  This also includes information about USB security tokens.
$oJson = ObjCreate("Chilkat.JsonObject")
$bSuccess = $oScard.FindSmartcards($oJson)
If ($bSuccess = False) Then
    ConsoleWrite($oScard.LastErrorText & @CRLF)
    Exit
EndIf

;  When writing this example, I have 3 smart card readers plugged into my system.
;  One of them has a smart card inserted.
;  Here's the JSON returned by FindSmartcards...

;  {
;    "reader": [
;      {
;        "name": "Alcor Micro USB Smart Card Reader 0",
;        "state": "empty"
;      },
;      {
;        "name": "Generic Smart Card Reader Interface 0",
;        "state": "present",
;        "vendorName": "Generic",
;        "serialNumber": "3230303730383138303030303030303030",
;        "systemName": "Generic Smart Card Reader Interface 0",
;        "card": {
;          "atr": "3BFC180000813180459067464A00641606F2727E00E0",
;          "windows": {
;            "miniDriver": "tagliov70px.dll",
;            "cryptoProvider": "Microsoft Base Smart Card Crypto Provider",
;            "keyStorageProvider": "Microsoft Smart Card Key Storage Provider"
;          }
;        }
;      },
;      {
;        "name": "SCM Microsystems Inc. SCR33x USB Smart Card Reader 0",
;        "state": "empty"
;      }
;    ]
;  }

$oJson.EmitCompact = False
ConsoleWrite($oJson.Emit() & @CRLF)
ConsoleWrite(" " & @CRLF)

;  We can iterate over the JSON to find the readers with a smart card already inserted..
Local $sName
$oSbState = ObjCreate("Chilkat.StringBuilder")

Local $i = 0
Local $iCount_i = $oJson.SizeOfArray("reader")
While $i < $iCount_i
    $oJson.I = $i
    $sName = $oJson.StringOf("reader[i].name")

    $oSbState.Clear 
    $oJson.StringOfSb("reader[i].state",$oSbState)

    If ($oSbState.Contains("present",True) = True) Then
        ConsoleWrite($sName & " has a smart card inserted." & @CRLF)
    Else
        ConsoleWrite($sName & " does not have a smart card inserted." & @CRLF)
    EndIf

    $i = $i + 1
Wend
ConsoleWrite(" " & @CRLF)

;  Now let's begin the code to wait for a change (where a smart card gets inserted or removed)

;  Get the list of all readers.
$oStReaders = ObjCreate("Chilkat.StringTable")
$bSuccess = $oScard.ListReaders($oStReaders)
If ($bSuccess = False) Then
    ConsoleWrite($oScard.LastErrorText & @CRLF)
    Exit
EndIf

;  Show the reader names..
Local $iNumReaders = $oStReaders.Count
$i = 0
While $i < $iNumReaders
    ConsoleWrite($i & ": " & $oStReaders.StringAt($i) & @CRLF)
    $i = $i + 1
Wend

;  Sample output from the above loop.
;  0: Alcor Micro USB Smart Card Reader 0
;  1: Generic Smart Card Reader Interface 0
;  2: SCM Microsystems Inc. SCR33x USB Smart Card Reader 0
;  

;  Synchronously wait 30 seconds for a card to be inserted or removed from any of the above readers.
$oJson2 = ObjCreate("Chilkat.JsonObject")
$bSuccess = $oScard.GetStatusChange(30000,$oStReaders,$oJson2)
If ($bSuccess = False) Then
    ConsoleWrite($oScard.LastErrorText & @CRLF)
    Exit
EndIf

ConsoleWrite(" " & @CRLF)

;  Let's see what happened...
$oJson2.EmitCompact = False
ConsoleWrite($oJson2.Emit() & @CRLF)
ConsoleWrite(" " & @CRLF)

;  This is what json2 contains.
;  A card was inserted into the reader named "SCM Microsystems Inc. SCR33x USB Smart Card Reader 0"
;  The "numChanged" indicates that one reader's status changed.  
;  The "changed":true indicates the reader that changed.   The state is now "present".

;  {
;    "numChanged": 1,
;    "reader": [
;      {
;        "name": "Alcor Micro USB Smart Card Reader 0",
;        "changed": false,
;        "state": "empty"
;      },
;      {
;        "name": "Generic Smart Card Reader Interface 0",
;        "changed": false,
;        "state": "present",
;        "atr": "3BFC180000813180459067464A00641606F2727E00E0"
;      },
;      {
;        "name": "SCM Microsystems Inc. SCR33x USB Smart Card Reader 0",
;        "changed": true,
;        "state": "present",
;        "atr": "3BDF96FF8131FE455A018048494443313158587300011B09"
;      }
;    ]
;  }

;  Find the reader that changed...
Local $bChanged
Local $state
Local $sAtr

Local $iNumChanged = $oJson2.IntOf("numChanged")
ConsoleWrite("number of readers with a changed state: " & $iNumChanged & @CRLF)

$i = 0
$iCount_i = $oJson2.SizeOfArray("reader")
While $i < $iCount_i
    $oJson2.I = $i
    $bChanged = $oJson2.BoolOf("reader[i].changed")
    If ($bChanged = True) Then
        $sName = $oJson2.StringOf("reader[i].name")
        $state = $oJson2.StringOf("reader[i].state")

        ConsoleWrite("Changed: " & @CRLF)
        ConsoleWrite("    reader name: " & $sName & @CRLF)
        ConsoleWrite("    new state: " & $state & @CRLF)

        ;  If a card is now in this reader, we should have the ATR of the card..
        If ($oJson2.HasMember("reader[i].atr") = True) Then
            $sAtr = $oJson2.StringOf("reader[i].atr")
            ConsoleWrite("    ATR of card inserted into this reader: " & $sAtr & @CRLF)
        EndIf

    EndIf

    $i = $i + 1
Wend

;  The output from the above loop:

;  number of readers with a changed state: 1
;  Changed: 
;      reader name: SCM Microsystems Inc. SCR33x USB Smart Card Reader 0
;      new state: present
;      ATR of card inserted into this reader: 3BDF96FF8131FE455A018048494443313158587300011B09

;  Applications should always release the context when finished.
$bSuccess = $oScard.ReleaseContext()
If ($bSuccess = False) Then
    ConsoleWrite($oScard.LastErrorText & @CRLF)
EndIf