Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Gli oggetti servizio Microsoft Point of Service per .NET (POS per .NET) continuamente tengono traccia e aggiornano continuamente una serie di statistiche sui dispositivi per ogni dispositivo connesso. Il rilevamento delle statistiche viene eseguito usando la DeviceStatistics classe , che contiene metodi per la reimpostazione, il recupero e l'aggiornamento delle statistiche, nonché metodi helper per la creazione di statistiche, l'incremento delle statistiche e il caricamento o il salvataggio delle statistiche da o verso l'archiviazione file XML.
La creazione di report sulle statistiche in POS per .NET supporta statistiche archiviate in hardware o software. Le statistiche basate sul software vengono archiviate in un file di statistiche XML, \Program Files\Common Files\Microsoft Shared\Point of Service\Statistics\PosDeviceStatistics.xmle aggiornate a un intervallo di scaricamento definito a livello globale, determinato al momento dell'installazione e della configurazione del sistema. Per impostazione predefinita, questo intervallo di scaricamento è di 1 secondo. Quando l'applicazione richiede un dispositivo, POS per .NET carica le statistiche appropriate dal file XML.
La gestione delle statistiche specifiche del dispositivo è supportata dall'interfaccia della classe di dispositivo Base o Basic . Gli oggetti servizio che ereditano da una classe Base o Basic sono in genere necessari solo per chiamare IncrementStatistic, che incrementa il valore di una statistica specificata o SetStatistic, che imposta una statistica su un valore specificato. Tutte le altre implementazioni delle statistiche vengono fornite dall'interfaccia della classe Base o Basic .
I membri chiave della classe DeviceStatistics sono descritti in dettaglio di seguito:
CapStatisticsReporting identifica le funzionalità di creazione di report delle statistiche del dispositivo. Quando CapStatisticsReporting è impostato su false, non sono disponibili dati statistici relativi al dispositivo. Se CapStatisticsReporting è true, sono disponibili alcuni dati statistici e il dispositivo può iniziare ad accumulare varie statistiche relative all'utilizzo. Le informazioni accumulate e segnalate sono specifiche del dispositivo e vengono recuperate usando il metodo RetrieveStatistics .
CapUpdateStatistics definisce se le statistiche raccolte possono essere reimpostate o aggiornate da un'applicazione che utilizza i metodi UpdateStatistics e ResetStatistics . Questa proprietà è valida solo se CapStatisticsReporting è true. Se CapStatisticsReporting è false, la proprietà CapUpdateStatistics è sempre false.
ResetStatistics può essere chiamato solo se sia CapStatisticsReporting che CapUpdateStatistics sono true. Questo metodo reimposta una, alcune o tutte le statistiche del dispositivo reimpostabili su zero. Reimposta le statistiche definite reimpostabili all'interno di un dispositivo su zero. Per completare correttamente questo metodo, tutte le statistiche richieste devono essere reimpostate correttamente. In caso contrario, viene generato un errore con il metodo ErrorCode esteso. Questo metodo viene sempre eseguito in modo sincrono.
UpdateStatistics imposta una, alcune o tutte le statistiche del dispositivo reimpostabili sui valori specificati. Per completare correttamente questo metodo, tutte le statistiche richieste devono essere aggiornate correttamente. Se alcuni non possono essere aggiornati per qualsiasi motivo, viene restituito un evento ErrorCode . Sia CapStatisticsReporting che CapUpdateStatistics devono essere impostati su true per chiamare questo metodo. Il metodo UpdateStatistics viene sempre eseguito in modo sincrono.
RetrieveStatistics recupera le statistiche richieste da un dispositivo. CapStatisticsReporting deve essere true per poter utilizzare correttamente questo metodo. Tutte le chiamate a RetrieveStatistics restituiranno il codice XML seguente come minimo.
<?xml version='1.0'?> <UPOSStat version="1.10.0" xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance xmlns="http://www.nrf-arts.org/IXRetail/namespace/" xsi:schemaLocation="http://www.nrf-arts.org/IXRetail/namespace/ UPOSStat.xsd"> <Event> <Parameter> <Name>RequestedStatistic</Name> <Value>1234</Value> </Parameter> </Event> <Equipment> <UnifiedPOSVersion>1.10</UnifiedPOSVersion> <DeviceCategory UPOS="CashDrawer"/> <ManufacturerName>Cashdrawers R Us</ManufacturerName> <ModelName>CD-123</ModelName> <SerialNumber>12345</SerialNumber> <FirmwareRevision>1.0 Rev. B</FirmwareRevision> <Interface>RS232</Interface> <InstallationDate>2000-03-01</InstallationDate> </Equipment> </UPOSStat>Se l'applicazione richiede un nome di statistica che il dispositivo non supporta, la
<Parameter>voce verrà restituita con un oggetto vuoto<Value>. Per esempio:<Parameter> <Name>RequestedStatistic</Name> <Value></Value> </Parameter>Tutte le statistiche raccolte dal dispositivo che sono specifiche del produttore e non definite nello schema verranno restituite in un
<ManufacturerSpecific>tag anziché in un<Parameter>tag. Per esempio:<ManufacturerSpecific> <Name>TheAnswer</Name> <Value>42</Value> </ManufacturerSpecific>Quando un'applicazione richiede tutte le statistiche dal dispositivo, il dispositivo restituisce una voce
<Parameter>per ogni statistica definita nella categoria del dispositivo. La categoria di dispositivi è definita dalla versione di XML Schema specificata dall'attributoversionnel<UPOSStat>tag . Se il dispositivo non registra statistiche, il<Value>tag sarà vuoto.
POS per .NET usa i gestori per eseguire la lettura e la scrittura di statistiche in modo simile al modo in cui vengono gestiti gli eventi. Quando viene creato uno di questi gestori di statistiche, viene assegnato a una particolare statistica del dispositivo. Quando questa statistica viene letta o aggiornata, il gestore chiama un delegato in grado di leggere o scrivere nel dispositivo in base alle esigenze.
I gestori statistiche usano diversi tipi di delegati per eseguire diverse operazioni statistiche. GetStatistic i delegati vengono usati per recuperare i valori delle statistiche, mentre SetStatistic i delegati assegnano valori statistici. I delegati GetStatistics accettano il nome della statistica da recuperare come parametro e restituiscono una stringa che rappresenta il valore di tale statistica. I delegati SetStatistic accettano il nome della statistica da modificare e il valore da assegnare a tale statistica come parametri. I delegati SetStatistic non restituiscono valori.
I gestori delle statistiche possono essere assegnati a una delle statistiche standard definite dalla specifica Unified Point Of Service (UnifiedPOS), ma sono supportati anche gestori personalizzati per tutte le statistiche create tramite CreateStatistic dal codice oggetto del servizio.
Example
L'esempio di codice seguente illustra come abilitare, gestire e recuperare i dati delle statistiche da un dispositivo MSR.
// File FORM1.CS
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.IO;
using Microsoft.PointOfService;
using Microsoft.PointOfService.BaseServiceObjects;
namespace Statistics
{
public partial class SampleStatistics : Form
{
// Indicates whether or not the Service Object has
// been started.
bool ServiceObjectStarted = false;
// The Service Object.
PosCommon so = null;
public SampleStatistics()
{
InitializeComponent();
// Disable the buttons until the SO is loaded successfully.
UpdateControls();
}
public void UpdateControls()
{
btnGenerateStatistics.Enabled = ServiceObjectStarted;
btnRetrieveStatistics.Enabled = ServiceObjectStarted ;
txtStatisticName.Enabled = ServiceObjectStarted;
// The statistic name text box is disabled until the
// Service Object is loaded.
if (ServiceObjectStarted)
{
btnStartSO.Text = "Close SO";
}
else
{
txtStatisticName.Clear();
txtRetrievedStatistics.Clear();
btnStartSO.Text = "Start SO";
}
// The retrieve one statistic button is disabled until
// the user has entered a statistic name.
if (txtStatisticName.TextLength > 0)
{
btnRetrieveStatistic.Enabled = true;
}
else
{
btnRetrieveStatistic.Enabled = false;
}
}
private void StartServiceObject(object sender, EventArgs e)
{
PosExplorer explorer = new PosExplorer(this);
string SOName = "SampleStatistics";
if (ServiceObjectStarted)
{
so.DeviceEnabled = false;
so.Close();
so = null;
ServiceObjectStarted = false;
UpdateControls();
}
else
{
foreach (DeviceInfo d in explorer.GetDevices())
{
if (d.ServiceObjectName == SOName)
{
try
{
// Standard Service Object startup.
so = explorer.CreateInstance(d)
as PosCommon;
so.Open();
so.Claim(0);
so.DeviceEnabled = true;
// Application-specific setup.
ServiceObjectStarted = true;
UpdateControls();
}
catch
{
// Something went wrong starting the SO
MessageBox.Show("The Service Object '" +
SOName + "' failed to load",
"Service Object Error",
MessageBoxButtons.OK,
MessageBoxIcon.Exclamation);
return;
}
break;
}
}
if (so == null)
{
// No Service Object with the
// specified name could be found.
MessageBox.Show("The Service Object '" +
SOName + "' could not be found",
"Service Object Error",
MessageBoxButtons.OK,
MessageBoxIcon.Exclamation);
}
}
}
private void GenerateStatistics(object sender, EventArgs e)
{
// In this example case, you use this
// property to tell the Service Object to change statistic
// values.
so.DeviceEnabled = true;
// Report status.
txtRetrievedStatistics.Text = "DeviceEnabled called to" +
" to modify statistic values.";
}
private void RetrieveStatistics(object sender, EventArgs e)
{
string statistics;
bool IsXml = true;
try
{
statistics = so.RetrieveStatistics();
}
catch
{
statistics = "No statistics found";
IsXml = false;
}
DisplayStatistics(statistics, IsXml);
}
private void RetrieveOneStatistic(object sender, EventArgs e)
{
string statistics;
bool IsXml = true;
try
{
statistics = so.RetrieveStatistic(
txtStatisticName.Text);
}
catch
{
statistics = "Statistic not found: " +
txtStatisticName.Text;
IsXml = false;
}
DisplayStatistics(statistics, IsXml);
txtStatisticName.Clear();
btnRetrieveStatistic.Enabled = false;
}
private void StatisticSizeChanged(object sender, EventArgs e)
{
if (txtStatisticName.TextLength > 0)
{
btnRetrieveStatistic.Enabled = true;
}
else
{
btnRetrieveStatistic.Enabled = false;
}
}
// When retrieving statistics, POS for .NET returns a block
// of XML (as specified in the UPOS specification). This
// method will make it look readable with white space
// and indenting and then display it in the text box.
private void DisplayStatistics(string inputString, bool isXml)
{
string s = null;
// In case of an exception, you do not have an XML
// string, so just display the error description. Otherwise,
// load the XML string into an XmlDocument object and
// make it look readable.
if (!isXml)
{
s = inputString;
}
if(isXml)
{
// Create new XML document and load the statistics
// XML string.
XmlDocument doc = new XmlDocument();
doc.LoadXml(inputString);
// Create a XmlTextWriter using a MemoryStream and
// tell it to indent the XML output (so that it is
// readable.)
MemoryStream m = new MemoryStream();
XmlTextWriter writer = new XmlTextWriter(m, null);
writer.Formatting = Formatting.Indented;
writer.Indentation = 4;
// Save the document to the memory stream using the
// XmlWriter.
doc.Save(writer);
// The stream will be encoded as UTF8, so convert the
// buffer into a string.
UTF8Encoding u = new UTF8Encoding();
s = u.GetString(m.GetBuffer());
}
// Write the string to the text box.
txtRetrievedStatistics.Text = s;
}
}
}
// File FORM1.DESIGNER.CS
namespace Statistics
{
partial class SampleStatistics
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.btnStartSO = new System.Windows.Forms.Button();
this.btnGenerateStatistics = new System.Windows.Forms.Button();
this.btnRetrieveStatistics = new System.Windows.Forms.Button();
this.txtStatisticName = new System.Windows.Forms.TextBox();
this.txtRetrievedStatistics = new System.Windows.Forms.TextBox();
this.btnRetrieveStatistic = new System.Windows.Forms.Button();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.groupBox1.SuspendLayout();
this.SuspendLayout();
//
// btnStartSO
//
this.btnStartSO.Location = new System.Drawing.Point(45, 35);
this.btnStartSO.Name = "btnStartSO";
this.btnStartSO.Size = new System.Drawing.Size(133, 23);
this.btnStartSO.TabIndex = 0;
this.btnStartSO.Text = "Start SO";
this.btnStartSO.UseVisualStyleBackColor = true;
this.btnStartSO.Click += new System.EventHandler(this.StartServiceObject);
//
// btnGenerateStatistics
//
this.btnGenerateStatistics.Location = new System.Drawing.Point(45, 75);
this.btnGenerateStatistics.Name = "btnGenerateStatistics";
this.btnGenerateStatistics.Size = new System.Drawing.Size(133, 23);
this.btnGenerateStatistics.TabIndex = 1;
this.btnGenerateStatistics.Text = "GenerateStatistics";
this.btnGenerateStatistics.UseVisualStyleBackColor = true;
this.btnGenerateStatistics.Click += new System.EventHandler(this.GenerateStatistics);
//
// btnRetrieveStatistics
//
this.btnRetrieveStatistics.Location = new System.Drawing.Point(45, 117);
this.btnRetrieveStatistics.Name = "btnRetrieveStatistics";
this.btnRetrieveStatistics.Size = new System.Drawing.Size(133, 23);
this.btnRetrieveStatistics.TabIndex = 2;
this.btnRetrieveStatistics.Text = "Retrieve Statistics";
this.btnRetrieveStatistics.UseVisualStyleBackColor = true;
this.btnRetrieveStatistics.Click += new System.EventHandler(this.RetrieveStatistics);
//
// txtStatisticName
//
this.txtStatisticName.Location = new System.Drawing.Point(16, 68);
this.txtStatisticName.Name = "txtStatisticName";
this.txtStatisticName.Size = new System.Drawing.Size(205, 20);
this.txtStatisticName.TabIndex = 4;
this.txtStatisticName.TextChanged += new System.EventHandler(this.StatisticSizeChanged);
//
// txtRetrievedStatistics
//
this.txtRetrievedStatistics.BackColor = System.Drawing.Color.White;
this.txtRetrievedStatistics.Location = new System.Drawing.Point(45, 157);
this.txtRetrievedStatistics.Multiline = true;
this.txtRetrievedStatistics.Name = "txtRetrievedStatistics";
this.txtRetrievedStatistics.ReadOnly = true;
this.txtRetrievedStatistics.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.txtRetrievedStatistics.Size = new System.Drawing.Size(476, 247);
this.txtRetrievedStatistics.TabIndex = 5;
//
// btnRetrieveStatistic
//
this.btnRetrieveStatistic.Location = new System.Drawing.Point(16, 30);
this.btnRetrieveStatistic.Name = "btnRetrieveStatistic";
this.btnRetrieveStatistic.Size = new System.Drawing.Size(133, 23);
this.btnRetrieveStatistic.TabIndex = 6;
this.btnRetrieveStatistic.Text = "Retrieve Statistic";
this.btnRetrieveStatistic.UseVisualStyleBackColor = true;
this.btnRetrieveStatistic.Click += new System.EventHandler(this.RetrieveOneStatistic);
//
// groupBox1
//
this.groupBox1.Controls.Add(this.btnRetrieveStatistic);
this.groupBox1.Controls.Add(this.txtStatisticName);
this.groupBox1.Location = new System.Drawing.Point(219, 35);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(302, 105);
this.groupBox1.TabIndex = 7;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "Single Statistic";
//
// SampleStatistics
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.SystemColors.MenuBar;
this.ClientSize = new System.Drawing.Size(565, 439);
this.Controls.Add(this.groupBox1);
this.Controls.Add(this.txtRetrievedStatistics);
this.Controls.Add(this.btnRetrieveStatistics);
this.Controls.Add(this.btnGenerateStatistics);
this.Controls.Add(this.btnStartSO);
this.Name = "SampleStatistics";
this.Text = "Form1";
this.groupBox1.ResumeLayout(false);
this.groupBox1.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button btnStartSO;
private System.Windows.Forms.Button btnGenerateStatistics;
private System.Windows.Forms.Button btnRetrieveStatistics;
private System.Windows.Forms.TextBox txtStatisticName;
private System.Windows.Forms.TextBox txtRetrievedStatistics;
private System.Windows.Forms.Button btnRetrieveStatistic;
private System.Windows.Forms.GroupBox groupBox1;
}
}
// File STATISTICSSO.CS
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.PointOfService;
using Microsoft.PointOfService.BaseServiceObjects;
[assembly: PosAssembly("Service Object Contractors, Inc.")]
namespace SOSamples.Statistics
{
[ServiceObject(DeviceType.Msr,
"SampleStatistics",
"Sample Statistics Service Object",
1,
9)]
public class StatisticsTest : MsrBase
{
// This will be incremented every time DeviceEnabled
// is set so that different sets of demonstration
// statistics can be generated.
int enableCount = 0;
// The name of a custom created statistic used to demonstrate
// custom Statistic handlers.
private const string PollingStatistic = "Polling Interval";
// Statistic used to demonstrate IncrementStatistic.
private const string TestIncrement = "MyIncrementableStat";
// String returned from CheckHealth
private string MyHealthText;
public StatisticsTest()
{
DevicePath = "Sample Statistics";
}
// This is the delegate which will be called for each
// statistic that we have associated with this delegate by
// calling SetStatisticHandler().
//
// Delegates like this should most commonly be used
// to get and set statistics in hardware. The delegate
// allows the POS for .NET statistic subsystem to query
// the value of a statistic in real time, before it is
// returned to the application.
private string GetHardwareInfo(string name)
{
// Add your code to query values from hardware here.
// Very simple demonstration: just return the name
// of the statistic as its value;
return name;
}
// In a typical Service Object implementation, statistics
// will be modified throughout the Service Object code. This
// method demonstrates the methods used to modify statistic
// values.
public void SetDemonstrationStatistics()
{
// IncrementStatistic can be used to easily
// increment a numeric statistic.
IncrementStatistic(TestIncrement);
switch(enableCount)
{
case 0:
SetStatisticValue(StatisticManufacturerName,
"Microsoft Corporation");
break;
case 1:
SetStatisticValue(StatisticManufacturerName,
"Service Control Contractors, Inc.");
break;
case 2:
SetStatisticValue(StatisticManufacturerName,
"Point of Service Controls .com");
break;
}
if (++enableCount == 3 )
{
enableCount = 0;
}
}
#region PosCommon overrides
// Returns the result of the last call to CheckHealth()
public override void Open()
{
base.Open();
// In your implementation of Open(), your Service Object
// code should:
// 1. Initialize statistics.
// 2. Create custom statistics.
// 3. Set statistic handlers for hardware Statistics.
// 1. Initialize statistics
SetStatisticValue(StatisticManufacturerName,
"Microsoft Corporation");
SetStatisticValue(StatisticManufactureDate,
"2004-10-23");
SetStatisticValue(StatisticModelName,
"Statistic Sample");
SetStatisticValue(StatisticMechanicalRevision,
"1.0");
SetStatisticValue(StatisticInterface,
"USB");
// 2a. Create a new statistic to test Increment
// method. No custom handler needed.
CreateStatistic(TestIncrement, false, "blobs");
// 2b. Create a new manufacturer statistic to demonstrate
// custom attributes with StatisticHandlers.
CreateStatistic(PollingStatistic, false,
"milliseconds");
// 3. Set handlers for statistics stored in hardware.
SetStatisticHandlers(PollingStatistic,
new GetStatistic(GetHardwareInfo), null);
SetStatisticHandlers(StatisticSerialNumber,
new GetStatistic(GetHardwareInfo), null);
}
public override bool DeviceEnabled
{
get
{
return base.DeviceEnabled;
}
set
{
// This method will set various statistics to
// demonstrate the statistic APIs. We are going
// to change statistic values every time the device
// is enabled. This operation is just for
// demonstration and would not be found in live code.
SetDemonstrationStatistics();
base.DeviceEnabled = value;
}
}
public override string CheckHealthText
{
get
{
// MsrBasic.VerifyState(musBeClaimed,
// mustBeEnabled). This may throw an exception
VerifyState(false, false);
return MyHealthText;
}
}
public override string CheckHealth(
HealthCheckLevel level)
{
// Verify that device is open, claimed, and enabled.
VerifyState(true, true);
// Your code here:
// check the health of the device and return a
// descriptive string.
// Cache result in the CheckHealthText property.
MyHealthText = "Ok";
return MyHealthText;
}
public override DirectIOData DirectIO(
int command,
int data,
object obj)
{
// Verify that the device is open.
VerifyState(false, false);
return new DirectIOData(data, obj);
}
#endregion PosCommon overrides
#region MsrBasic Overrides
protected override MsrFieldData ParseMsrFieldData(
byte[] track1Data,
byte[] track2Data,
byte[] track3Data,
byte[] track4Data,
CardType cardType)
{
// Your code here:
// Implement this method to parse track data
// into fields which will be returned as
// properties to the application (e.g.,FirstName,
// AccountNumber, etc.)
return new MsrFieldData();
}
protected override MsrTrackData ParseMsrTrackData(
byte[] track1Data,
byte[] track2Data,
byte[] track3Data,
byte[] track4Data,
CardType cardType)
{
// Your code here:
// Implement this method to convert raw track data.
return new MsrTrackData();
}
#endregion MsrBasic Overrides
}
}
Compilazione del codice
- Per altre informazioni sulla creazione e la compilazione di un progetto oggetto servizio, vedere Esempi di oggetti servizio: Introduzione.