У меня есть приложение UWP, которое использует устройство чтения смарт-карт (устройство: ACR122u от ACS) для считывания меток RFID. Он работает, когда я запускаю его на своей локальной машине, и работает также на целевом компьютерном устройстве. Но когда я запускаю то же самое, с тем же пользователем, но в режиме киоска (Назначенный доступ), это не работает. И я не знаю, как я могу отладить это в режиме киоска. так что я не нахожу проблему.
Системная информация : развернутая версия: Windows 10 (1903 / Build 18362) Целевой компьютер: Windows 10 (1903)
Мое решение основано на этом Пример :
Mainview:
public sealed partial class MainPage : Page
{
//RFID
private RFIDManager _RFIDManager;
public bool RFIDScannerIsActivated { get; set; }
public string LastScannedRFID { get; set; }
// GUI
public enum StatusGUI { Login }
private StatusGUI _GUIStatus;
private StatusGUI GUIStatus
{
get { return _GUIStatus; }
set
{
_GUIStatus = value;
SetStatus(value);
}
}
private PersonDTO _LoggedInPerson;
public PersonDTO LoggedinPerson
{
get { return _LoggedInPerson; }
set
{
_LoggedInPerson = value;
SetLoggedInAs();
}
}
// Services
private readonly LendService lendServie;
public MainPage()
{
try
{
lendServie = new LendService();
Translations.Init(ResourceLoader.GetForViewIndependentUse());
this.InitializeComponent();
InitTranslations();
InitializeRFID();
VersionNumber.Text = VersionHelper.GetVersionFormated();
GUIStatus = StatusGUI.Login;
}
catch (Exception ex)
{
ShowErrorAndShutDown();
}
}
#region Init
private async void InitTranslations()
{
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
PlsLoginLabel.Text = Translations.Translate(WordKeys.PleaseLoginWhitYourBadge);
ScentalogyLibraryLabel.Text = Translations.Translate(WordKeys.ScentalogyLibrary);
PleaseWaitLabel.Text = Translations.Translate(WordKeys.PleaseWait);
});
}
private void InitializeRFID()
{
try
{
_RFIDManager = new RFIDManager();
_RFIDManager.ConnectionChangedEvent += RFIDManager_ConnectionStatusChanged;
_RFIDManager.MessageReceivedEvent += RFIDManager_MessageReceived;
_RFIDManager.ExceptionRaisedEvent += RFIDManager_ExceptionRaised;
_RFIDManager.StartRFIDReader();
}
catch (Exception e)
{
Trace.WriteLine(e.Message);
throw e;
}
}
#endregion
#region Input Events
private async void RFIDManager_MessageReceived(object sender, MessageReceivedEventArgs args)
{
ShowLoadingIndicator(true);
try
{
if (LastScannedRFID != args.Data && GUIStatus == StatusGUI.Login)
{
LastScannedRFID = args.Data;
LoggedinPerson = null;
LoggedinPerson = await lendServie.GetMyUserInfosWithBadgeNumber(LastScannedRFID);
Trace.WriteLine(LastScannedRFID);
if (!string.IsNullOrEmpty(LastScannedRFID) && GUIStatus == StatusGUI.Login)
{
SetLoggedInAs();
}
}
}
catch (Exception ex)
{
ShowErrorMessagAndRestart();
}
ShowLoadingIndicator(false);
}
#endregion
#region GUI
private void SetStatus(StatusGUI status)
{
CollapseAll();
switch (status)
{
case StatusGUI.Login:
Login.Visibility = Visibility.Visible;
LastScannedRFID = null;
LoggedinPerson = null;
break;
default:
Login.Visibility = Visibility.Visible;
break;
}
}
private void CollapseAll()
{
Login.Visibility = Visibility.Collapsed;
}
#endregion
#region GUI Helper Logic
private async void SetLoggedInAs()
{
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
LogedInAsBorder.Visibility = LoggedinPerson != null ? Visibility.Visible : Visibility.Collapsed;
LogedInAs.Text = LoggedinPerson != null ? Translations.Translate(WordKeys.LoggedInAs) + " " + LoggedinPerson.UserName + " (" + LoggedinPerson.BadgeNumber +")": "";
});
}
private async void ShowLoadingIndicator(bool show)
{
Visibility visibility;
if (show)
{
visibility = Visibility.Visible;
}
else
{
visibility = Visibility.Collapsed;
}
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
LoadingIndicator.Visibility = visibility;
});
}
private async void ShowErrorMessagAndRestart()
{
var messageDialog = new MessageDialog(Translations.Translate(WordKeys.UnknownErrorContactServiceDesk) + Environment.NewLine + Translations.Translate(WordKeys.TheDeviceWillRestart),Translations.Translate(WordKeys.Error));
await messageDialog.ShowAsync();
Windows.System.ShutdownManager.BeginShutdown(Windows.System.ShutdownKind.Restart, TimeSpan.FromSeconds(0));
}
private async void ShowErrorAndShutDown()
{
var messageDialog = new MessageDialog(Translations.Translate(WordKeys.UnknownErrorContactServiceDesk) + Environment.NewLine + Translations.Translate(WordKeys.TheDeviceWillShutDown), Translations.Translate(WordKeys.Error));
await messageDialog.ShowAsync();
Windows.System.ShutdownManager.BeginShutdown(Windows.System.ShutdownKind.Shutdown, TimeSpan.FromSeconds(0));
}
#endregion
#region RFID Events Others
private void RFIDManager_ConnectionStatusChanged(object sender, ConnectionChangedEventArgs args)
{
RFIDScannerIsActivated = args.IsConnected;
Trace.WriteLine("Status changed to: " + args.IsConnected);
}
private void RFIDManager_ExceptionRaised(object sender, RFIDExceptionRaisedEventArgs args)
{
Trace.WriteLine(args.Exception.Message);
}
#endregion
}
RFID Manager
public class RFIDManager : IDisposable
{
#region Fields
private SmartCardReader _smartCardReader;
private bool _rfidScannerIsActivated;
private CancellationTokenSource _CancellationTokenSource;
#endregion
/// <summary>
/// Initializes a new instance of the <see cref="RFIDManager"/> class. Start the RFID Reader with <seealso cref="StartRFIDReader"/> and receive the data from event <seealso cref="MessageReceivedEvent"/>
/// </summary>
public RFIDManager()
{
ReinitializeRFIDReader(false);
}
/// <summary>
/// Reinitializes the rfid reader. Starts the Reader if AutoStart is true
/// </summary>
/// <param name="autoStart">if set to <c>true</c> [automatic start].</param>
public void ReinitializeRFIDReader(bool autoStart = true)
{
try
{
StopRFIDReader();
if (autoStart)
{
StartRFIDReader();
}
}
catch (Exception e)
{
Log(e);
}
}
/// <summary>
/// Stops the rfid reader.
/// </summary>
public void StopRFIDReader()
{
try
{
_rfidScannerIsActivated = false;
// Clean up
if (_smartCardReader != null)
{
_smartCardReader.CardAdded -= CardReader_CardAdded;
_smartCardReader.CardRemoved -= CardReader_CardRemoved;
_smartCardReader = null;
}
if (_CancellationTokenSource != null)
{
_CancellationTokenSource.Dispose();
_CancellationTokenSource = null;
}
}
catch (Exception e)
{
Log(e);
}
finally
{
NotifyOnConnectionChanged(_rfidScannerIsActivated);
}
}
/// <summary>
/// Starts the rfid reader.
/// </summary>
public void StartRFIDReader()
{
//If no reader found, don't start
if (_rfidScannerIsActivated == true || _smartCardReader != null)
{
Log("RFID Reader is already running and can not be started again");
return;
}
InitializeRFID();
_rfidScannerIsActivated = true;
NotifyOnConnectionChanged(_rfidScannerIsActivated);
}
#region Private Methods
/// <summary>
/// Initializes the rfid reader to overwatch if a card is connected
/// </summary>
private async void InitializeRFID()
{
try
{
_CancellationTokenSource = new CancellationTokenSource();
// First try to find a reader that advertises as being NFC
var deviceInfo = await SmartCardReaderUtils.GetFirstSmartCardReaderInfo(SmartCardReaderKind.Nfc);
if (deviceInfo == null)
{
// If we didn't find an NFC reader, let's see if there's a "generic" reader meaning we're not sure what type it is
deviceInfo = await SmartCardReaderUtils.GetFirstSmartCardReaderInfo(SmartCardReaderKind.Any);
}
if (deviceInfo == null)
{
Log("NFC card reader mode not supported on this device");
return;
}
if (_smartCardReader == null)
{
_smartCardReader = await SmartCardReader.FromIdAsync(deviceInfo.Id);
_smartCardReader.CardAdded += CardReader_CardAdded;
_smartCardReader.CardRemoved += CardReader_CardRemoved;
}
}
catch (Exception e)
{
SendException(e);
}
}
#region RFID Requests
/// <summary>
/// Handles the card, if one is connected to the reader
/// </summary>
/// <param name="card">The card.</param>
private async Task HandleCard(SmartCard card)
{
try
{
// Connect to the card
using (SmartCardConnection connection = await card.ConnectAsync())
{
string currentUID = null;
// Try to identify what type of card it was
IccDetection cardIdentification = new IccDetection(card, connection);
await cardIdentification.DetectCardTypeAync();
Log("Connected to card\r\nPC/SC device class: " + cardIdentification.PcscDeviceClass.ToString());
Log("Card name: " + cardIdentification.PcscCardName.ToString());
Log("ATR: " + BitConverter.ToString(cardIdentification.Atr));
if ((cardIdentification.PcscDeviceClass == Pcsc.Common.DeviceClass.StorageClass) &&
(cardIdentification.PcscCardName == Pcsc.CardName.MifareUltralightC
|| cardIdentification.PcscCardName == Pcsc.CardName.MifareUltralight
|| cardIdentification.PcscCardName == Pcsc.CardName.MifareUltralightEV1))
{
// Handle MIFARE Ultralight
MifareUltralight.AccessHandler mifareULAccess = new MifareUltralight.AccessHandler(connection);
// Each read should get us 16 bytes/4 blocks, so doing
// 4 reads will get us all 64 bytes/16 blocks on the card
for (byte i = 0; i < 4; i++)
{
byte[] response = await mifareULAccess.ReadAsync((byte)(4 * i));
Log("Block " + (4 * i).ToString() + " to Block " + (4 * i + 3).ToString() + " " + BitConverter.ToString(response));
}
byte[] responseUid = await mifareULAccess.GetUidAsync();
currentUID = BitConverter.ToString(responseUid);
Log("UID: " + currentUID);
}
else if (cardIdentification.PcscDeviceClass == Pcsc.Common.DeviceClass.MifareDesfire)
{
// Handle MIFARE DESfire
Desfire.AccessHandler desfireAccess = new Desfire.AccessHandler(connection);
Desfire.CardDetails desfire = await desfireAccess.ReadCardDetailsAsync();
currentUID = BitConverter.ToString(desfire.UID);
Log("UID: " + currentUID);
Log("DesFire Card Details: " + Environment.NewLine + desfire.ToString());
}
else if (cardIdentification.PcscDeviceClass == Pcsc.Common.DeviceClass.StorageClass
&& cardIdentification.PcscCardName == Pcsc.CardName.FeliCa)
{
// Handle Felica
Log("Felica card detected");
var felicaAccess = new Felica.AccessHandler(connection);
var uid = await felicaAccess.GetUidAsync();
currentUID = BitConverter.ToString(uid);
Log("UID: " + currentUID);
}
else if (cardIdentification.PcscDeviceClass == Pcsc.Common.DeviceClass.StorageClass
&& (cardIdentification.PcscCardName == Pcsc.CardName.MifareStandard1K || cardIdentification.PcscCardName == Pcsc.CardName.MifareStandard4K))
{
// Handle MIFARE Standard/Classic
Log("MIFARE Standard/Classic card detected");
var mfStdAccess = new MifareStandard.AccessHandler(connection);
var uid = await mfStdAccess.GetUidAsync();
currentUID = BitConverter.ToString(uid);
Log("UID: " + currentUID);
ushort maxAddress = 0;
switch (cardIdentification.PcscCardName)
{
case Pcsc.CardName.MifareStandard1K:
maxAddress = 0x3f;
break;
case Pcsc.CardName.MifareStandard4K:
maxAddress = 0xff;
break;
}
await mfStdAccess.LoadKeyAsync(MifareStandard.DefaultKeys.FactoryDefault);
for (ushort address = 0; address <= maxAddress; address++)
{
var response = await mfStdAccess.ReadAsync(address, Pcsc.GeneralAuthenticate.GeneralAuthenticateKeyType.MifareKeyA);
Log("Block " + address.ToString() + " " + BitConverter.ToString(response));
}
}
else if (cardIdentification.PcscDeviceClass == Pcsc.Common.DeviceClass.StorageClass
&& (cardIdentification.PcscCardName == Pcsc.CardName.ICODE1 ||
cardIdentification.PcscCardName == Pcsc.CardName.ICODESLI ||
cardIdentification.PcscCardName == Pcsc.CardName.iCodeSL2))
{
// Handle ISO15693
Log("ISO15693 card detected");
var iso15693Access = new Iso15693.AccessHandler(connection);
var uid = await iso15693Access.GetUidAsync();
currentUID = BitConverter.ToString(uid);
Log("UID: " + currentUID);
}
else
{
// Unknown card type
// Note that when using the XDE emulator the card's ATR and type is not passed through, so we'll
// end up here even for known card types if using the XDE emulator
// Some cards might still let us query their UID with the PC/SC command, so let's try:
var apduRes = await connection.TransceiveAsync(new Pcsc.GetUid());
if (!apduRes.Succeeded)
{
Log("Failure getting UID of card, " + apduRes.ToString());
}
else
{
currentUID = BitConverter.ToString(apduRes.ResponseData);
Log("UID: " + currentUID);
}
}
NotifyOnScannedRFID(currentUID);
}
}
catch (Exception ex)
{
Log(ex);
}
}
#endregion
#endregion
#region Notification and Events
/// <summary>
/// Occurs when [The connection has changed].
/// </summary>
public event EventHandler<ConnectionChangedEventArgs> ConnectionChangedEvent;
/// <summary>
/// Occurs when [message has received].
/// </summary>
public event EventHandler<MessageReceivedEventArgs> MessageReceivedEvent;
/// <summary>
/// Occurs when [exception has raised].
/// </summary>
public event EventHandler<RFIDExceptionRaisedEventArgs> ExceptionRaisedEvent;
/// <summary>
/// Occurs when a logentry as information is send
/// </summary>
public event EventHandler<InformationNotificationEventArgs> InformationNotificationEvent;
/// <summary>
/// Notify Eventlistener for scanned RFID Value
/// </summary>
/// <param name="data">The data.</param>
public void NotifyOnScannedRFID(string data)
{
try
{
if(!string.IsNullOrWhiteSpace(data))
TaskHelper.ExecuteTaskOnMainThread(() => MessageReceivedEvent?.Invoke(this, new MessageReceivedEventArgs(data)));
}
catch (Exception e)
{
Log(e);
}
}
#region Private Eventhandling and Methods
private void CardReader_CardRemoved(SmartCardReader sender, CardRemovedEventArgs args)
{
Trace.WriteLine("Card removed");
}
private async void CardReader_CardAdded(SmartCardReader sender, CardAddedEventArgs args)
{
await HandleCard(args.SmartCard);
}
private void SendException(Exception exception, bool withStayRunning = false, [CallerMemberName]string memberName = null, [CallerFilePath]string filePath = null, [CallerLineNumber]int lineNumber = 0)
{
if (withStayRunning == false)
{
TaskHelper.ExecuteTaskOnMainThread(StopRFIDReader);
}
NotifyOnExceptionRaised(exception, memberName, filePath, lineNumber);
}
private void NotifyOnConnectionChanged(bool isConnected)
{
try
{
TaskHelper.ExecuteTaskOnMainThread(() => ConnectionChangedEvent?.Invoke(this, new ConnectionChangedEventArgs(isConnected)));
}
catch (Exception e)
{
Log(e);
}
}
private void NotifyOnExceptionRaised(Exception exception, [CallerMemberName]string memberName = null, [CallerFilePath]string filePath = null, [CallerLineNumber]int lineNumber = 0)
{
try
{
Trace.WriteLine(string.Format($"Member: {memberName}{Environment.NewLine}Filepath: {filePath}{Environment.NewLine}Linenumber: {lineNumber}{Environment.NewLine}Message: {exception.Message}"));
TaskHelper.ExecuteTaskOnMainThread(() => ExceptionRaisedEvent?.Invoke(this, new RFIDExceptionRaisedEventArgs(exception, memberName, filePath, lineNumber)));
}
catch (Exception e)
{
Trace.WriteLine(e.Message);
}
}
private void NotifyOnInformationNotification(string logText)
{
try
{
Trace.WriteLine(logText);
TaskHelper.ExecuteTaskOnMainThread(() => InformationNotificationEvent?.Invoke(this, new InformationNotificationEventArgs(logText)));
}
catch (Exception e)
{
Trace.WriteLine(e.Message);
}
}
private void Log(Exception exception, [CallerMemberName]string memberName = null, [CallerFilePath]string filePath = null, [CallerLineNumber]int lineNumber = 0)
{
NotifyOnExceptionRaised(exception, memberName, filePath, lineNumber);
}
private void Log(string logText, int errorCode, [CallerMemberName] string memberName = null, [CallerFilePath] string filePath = null, [CallerLineNumber] int lineNumber = 0)
{
if (!string.IsNullOrWhiteSpace(logText))
NotifyOnExceptionRaised(new RFIDReaderException(logText, errorCode), memberName, filePath, lineNumber);
}
private void Log(string logText)
{
if (!string.IsNullOrWhiteSpace(logText))
NotifyOnInformationNotification(logText);
}
#endregion
#endregion
public void Dispose()
{
StopRFIDReader();
}
}