Microsoft Point of Service for .NET (POS for .NET) サービス オブジェクトは、接続されている各デバイスのデバイス統計情報を継続的に追跡および更新します。 統計の追跡は、統計をリセット、取得、更新するためのメソッド、および統計の作成、統計のインクリメント、XML ファイル ストレージとの間での統計の読み込みまたは保存のためのヘルパー メソッドを含む、 DeviceStatistics クラスを使用して実行されます。
POS for .NET の統計レポートでは、ハードウェアまたはソフトウェアに格納されている統計がサポートされます。 ソフトウェア ベースの統計は、XML 統計ファイルに格納され、\Program Files\Common Files\Microsoft Shared\Point of Service\Statistics\PosDeviceStatistics.xmlされ、システムのインストールとセットアップ時に決定されるグローバルに定義されたフラッシュ間隔で更新されます。 既定では、このフラッシュ間隔は 1 秒です。 アプリケーションがデバイスを要求すると、POS for .NET は XML ファイルから適切な統計情報を読み込みます。
デバイス固有の統計管理は、 Base または Basic デバイス クラス インターフェイスでサポートされています。 通常、Base クラスまたは Basic クラスから継承するサービス オブジェクトは、IncrementStatistic を呼び出すためにのみ必要です。IncrementStatistic では、指定した統計情報の値がインクリメントされます。SetStatistic は、1 つの統計を指定した値に設定します。 その他の統計の実装はすべて、 Base クラスまたは Basic クラス インターフェイスによって提供されます。
DeviceStatistics クラスの主要なメンバーの詳細を次に示します。
CapStatisticsReporting は、デバイスの統計レポート機能を識別します。 CapStatisticsReporting が false に設定されている場合、デバイスに関する統計データは使用できません。 CapStatisticsReporting が true の場合、一部の統計データを使用でき、デバイスは使用状況に関するさまざまな統計情報の蓄積を開始する可能性があります。 蓄積および報告される情報はデバイス固有であり、 RetrieveStatistics メソッドを使用して取得されます。
CapUpdateStatistics では、UpdateStatistics メソッドと ResetStatistics メソッドを使用するアプリケーションによって、収集された統計をリセットまたは更新できるかどうかを定義します。 このプロパティは、 CapStatisticsReporting が true の場合にのみ有効です。 CapStatisticsReporting が false の場合、CapUpdateStatistics プロパティは常に false になります。
ResetStatistics は、 CapStatisticsReporting と CapUpdateStatistics の両方が true の場合にのみ呼び出すことができます。 このメソッドは、リセット可能なデバイス統計情報の 1 つ、一部、またはすべてをゼロにリセットします。 デバイスで定義されているリセット可能な統計情報が 0 にリセットされます。 このメソッドが正常に完了するには、要求されたすべての統計を正常にリセットする必要があります。 それ以外の場合は、Extended ErrorCode メソッドで エラーをスローします。 このメソッドは常に同期的に実行されます。
UpdateStatistics は 、リセット可能なデバイス統計情報の 1 つ、一部、またはすべてを指定された値に設定します。 このメソッドが正常に完了するためには、要求されたすべての統計を正常に更新する必要があります。 何らかの理由で更新できない場合は、 ErrorCode イベントが返されます。 このメソッドを呼び出すには 、CapStatisticsReporting と CapUpdateStatistics の両方を true に設定する必要があります。 UpdateStatistics メソッドは常に同期的に実行されます。
RetrieveStatistics は、 要求された統計をデバイスから取得します。 このメソッドを正常に使用するには、CapStatisticsReporting が true である必要があります。 RetrieveStatistics を呼び出すと、次の XML が最小値として返されます。
<?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>アプリケーションがデバイスでサポートされていない統計名を要求した場合、
<Parameter>エントリは空の<Value>で返されます。 例えば次が挙げられます。<Parameter> <Name>RequestedStatistic</Name> <Value></Value> </Parameter>スキーマで定義されていない製造元固有のデバイスによって収集されるすべての統計情報は、
<ManufacturerSpecific>タグではなく、<Parameter>タグで返されます。 例えば次が挙げられます。<ManufacturerSpecific> <Name>TheAnswer</Name> <Value>42</Value> </ManufacturerSpecific>アプリケーションがデバイスからすべての統計情報を要求すると、デバイスカテゴリで定義されているすべての統計情報に対して
<Parameter>エントリが返されます。 デバイス カテゴリは、versionタグの<UPOSStat>属性で指定された XML スキーマのバージョンによって定義されます。 デバイスが統計情報を記録しない場合、<Value>タグは空になります。
.NET 用 POS では、ハンドラーを使用して、イベントの処理方法と同様の方法で統計の読み取りと書き込みを実行します。 これらの統計ハンドラーのいずれかが作成されると、特定のデバイス統計に割り当てられます。 この統計情報が読み取りまたは更新されると、ハンドラーは、必要に応じてデバイスとの間で読み取りまたは書き込みを行うことができるデリゲートを呼び出します。
統計ハンドラーは、さまざまな種類のデリゲートを使用して、さまざまな統計操作を実行します。 GetStatistic デリゲートは統計値を取得するために使用され、デリゲート SetStatistic は統計値を割り当てます。 GetStatistics デリゲートは、パラメーターとして取得する統計の名前を取得し、その統計情報の値を表す文字列を返します。 SetStatistic デリゲートは、変更する統計の名前と、その統計にパラメーターとして割り当てられる値を受け取ります。 SetStatistic デリゲートは値を返しません。
統計ハンドラーは、Unified Point Of Service (UnifiedPOS) 仕様で定義されている標準統計のいずれかに割り当てることができますが、 CreateStatistic by Service Object コードを使用して作成されるすべての統計のカスタム ハンドラーもサポートされます。
Example
次のコード例は、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
}
}
コードのコンパイル
- サービス オブジェクト プロジェクトの作成とコンパイルの詳細については、「 サービス オブジェクト のサンプル: 作業の開始」を参照してください。
こちらもご覧ください
その他のリソース
.NET