You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用PCSC库的C# NFC项目报错:尝试结束不存在的事务

修复 "An attempt was made to end a non-existent transaction" 错误

问题根源

你的代码存在两个核心问题:

  1. 未启动PCSC事务:发送APDU命令前未启动事务,导致IsoReader释放时尝试结束一个不存在的事务,触发该错误。
  2. 无效的初始APDU命令:直接发送GetData命令(0xCA)不符合NFC标签交互逻辑,该命令需要先选中特定数据对象或应用才能生效。

修复步骤

1. 启动PCSC事务

创建IsoReader实例后,调用BeginTransaction()方法显式启动事务,确保释放时能正常结束事务。

2. 使用合法的初始命令

替换原有的GetData命令为ACR122U读卡器支持的获取UID命令(0xFF 0xCA 0x00 0x00 0x00),这是读取NFC标签最基础且通用的操作。

修正后的代码

using System;
using PCSC;
using PCSC.Iso7816;

class Program
{
    static void Main()
    {
        try
        {
            var contextFactory = ContextFactory.Instance;
            using (var context = contextFactory.Establish(SCardScope.System))
            {
                var readerNames = context.GetReaders();
                if (readerNames.Length == 0)
                {
                    Console.WriteLine("未找到读卡器。");
                    return;
                }

                var readerName = readerNames[0];
                Console.WriteLine($"使用读卡器:{readerName}");
                
                using (var isoReader = new IsoReader(context, readerName, SCardShareMode.Shared, SCardProtocol.Any, false))
                {
                    Console.WriteLine($"读卡器状态:{isoReader}");
                    
                    // 启动PCSC事务,解决事务结束错误
                    isoReader.BeginTransaction();

                    // 发送ACR122U专用命令获取NFC标签UID
                    var apdu = new CommandApdu(IsoCase.Case2Short, isoReader.ActiveProtocol)
                    {
                        CLA = 0xFF,       // 读卡器专用命令类
                        Instruction = 0xCA,// 获取UID指令
                        P1 = 0x00,
                        P2 = 0x00,
                        Le = 0x00         // 请求返回最大长度数据
                    };
                    Console.WriteLine($"发送APDU命令:{BitConverter.ToString(apdu.ToArray())}");

                    var response = isoReader.Transmit(apdu);
                    Console.WriteLine($"响应状态:SW1={response.SW1:X2}, SW2={response.SW2:X2}");
                    
                    if (response.HasData)
                    {
                        Console.WriteLine("NFC标签UID:");
                        Console.WriteLine(BitConverter.ToString(response.GetData()));
                    }
                    else
                    {
                        Console.WriteLine($"读取失败:SW1 SW2 = {response.SW1:X2} {response.SW2:X2}");
                    }
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"发生错误:{ex.Message}");
        }
    }
}

额外说明

  • 事务管理:IsoReader的using块会自动调用EndTransaction()方法,无需手动结束事务。
  • 命令适配:如果需要读取标签内的其他数据,需根据标签类型(如MIFARE Classic/Ultralight)发送对应的APDU命令,例如MIFARE Classic需要先验证密钥再读取扇区数据。

内容的提问来源于stack exchange,提问作者user26316631

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 04:37:05