Capture Helper¶
Capture Helper is the easiest and recommended way for adding the barcode scanning capabilities to a C# application (Windows or Xamarin).
Capture Helper Initialization¶
To use Capture Helper, first create an instance of Capture Helper
and register for the events your application requires and open
Capture Helper.
If opening Capture Helper returns an error such as
SktErrors.ESKT_UNABLEOPENDEVICE (-27)
, it might be because the Socket Mobile
Companion software is not installed or not running.
Here is a typical Capture Helper initialization:
public Form1()
{
InitializeComponent();
// initialize CaptureHelper
capture = new CaptureHelper()
{
// make the events running in UI Thread context
// Note this MUST be done on the UI thread. If not,
// UI updates from CaptureHelper will not occur
// Setting this is optional.
ContextForEvents = SynchronizationContext.Current;
};
// register for the Capture Helper events
capture.DeviceArrival += CaptureDeviceArrival;
capture.DeviceRemoval += CaptureDeviceRemoval;
capture.DeviceOwnershipChange += CaptureDeviceOwnershipChange;
capture.DecodedData += CaptureDecodedData;
capture.Errors += CaptureErrors;
capture.DevicePowerState += DevicePowerState;
capture.Terminate += Terminate;
...
}
Note
The line capture.ContextForEvents = SynchronizationContext.Current;
allows your application to handle the Capture Helper events directly in the User
Interface (UI) Thread context so the UI can be directly updated. Setting
ContextForEvents is optional, if none of the event handlers updates the UI
then this line can be removed.
CaptureHelper.ContextForEvents can ONLY be set on the UI thread.
CaptureHelper.ContextForEvents is a public member, so it can be set at any time.
Note
For Xamarin, if the UI has to be updated in the Capture event handlers and if
the System.Windows assembly is not used, it is probably best to use
RunOnUiThread()
and don’t specify any context for the events.
In the OnFormOpening override method of the form object proceed to open the communication between this application and Socket Mobile Companion software as shown below:
protected async override void OnFormOpening(FormOpeningEventArgs e)
{
base.OnFormOpening(e);
string appId = "windows:com.mycompany.myapp";
string developerId = "520CE559-D74D-4447-9E65-0E35512A0344";
string appKey = "MC3CFQD76T2AE/Jus4JJ6nxZJyub3WBxXgIVAKglTx239tKjR+LNspa46Y9io2w5";
long result = await capture.OpenAsync(appId, developerId, appKey);
if (!SktErrors.SKTSUCCESS(result))
{
labelCaptureVersion.Text = "Unable to connect to Socket Mobile Companion";
DialogResult dialogResult = MessageBox.Show(
"Unable to open Capture, is Socket Mobile Companion Service running?",
"Error",
MessageBoxButtons.OK,
MessageBoxIcon.Warning);
}
}
From that moment on, if a Socket Cordless Scanner connects to the host, the application CaptureDeviceArrival handler is invoked, and when the user then scans a barcode the CaptureDecodedData is invoked with the decoded data.
Note
For Xamarin, the websocket implementation is incomplete in the earlier version,
therefore it should be disabled by adding this line capture.DoNotUseWebSocket = true;
before calling the OpenAsync method.
Minimal implementation¶
Assuming the only thing that matters to the application is to receive the decoded data, a minimal implementation could be as simple as:
public Form1()
{
InitializeComponent();
// initialize CaptureHelper
capture = new CaptureHelper();
capture.ContextForEvents = WindowsFormsSynchronizationContext.Current;
capture.DecodedData += CaptureDecodedData;
string appId = "windows:com.mycompany.myapp";
string developerId = "520CE559-D74D-4447-9E65-0E35512A0344";
string appKey = "MC3CFQD76T2AE/Jus4JJ6nxZJyub3WBxXgIVAKglTx239tKjR+LNspa46Y9io2w5";
long result = await capture.OpenAsync(appId, developerId, appKey);
if (!SktErrors.SKTSUCCESS(result)) {
labelCaptureVersion.Text = "Unable to connect to Socket Mobile Companion";
}
}
async void CaptureDecodedData(object sender, CaptureHelper.DecodedDataArgs e)
{
textBoxDecodedData.Text = e.DecodedData.DataToUTF8String;
}
Of course this sample won’t help the user if for some reason the scanner is not connected to the host, or if there is an error occurring while using Capture. For these reasons we highly recommend to track the device presence, to handle the error event and to collect the Capture version.
Note
The line capture.ContextForEvents = WindowsFormsSynchronizationContext.Current;
allows the application to handle the Capture Helper events directly in the UI Thread
context so the UI can be directly updated.
If none of the event handlers updates the UI then this line can be removed.
Note
For Xamarin, if the UI has to be updated in the Capture event handlers and if
the System.Windows assembly is not used, it is probably best to use
RunOnUiThread()
and don’t specify any context for the events.
Note
For Xamarin, the websocket implementation is incomplete in the earlier version,
therefore it should be disabled by adding this line capture.DoNotUseWebSocket = true;
before calling the OpenAsync method.
Device connection awareness¶
This is a great way to confirm if the scanner is correctly connected to the
application or even to drive the UI when the scanner connects or scans.
Capture Helper automatically opens the device as soon as it receives its
connection notification. Once the device is open, Capture Helper fires the
device arrival event with a CaptureHelperDevice
instance to represent this
particular device. That CaptureHelperDevice
instance is used at each event
related to the device, and can be used to retrieve or configure the device
settings.
For an application to be aware of Device connections, there are 2 events that can be monitored: DeviceArrival and DeviceRemoval. Here is sample code on how to register for these events along with the DecodedData event. The devices are added into a ListBox in this particular case:
public Form1()
{
InitializeComponent();
// initialize CaptureHelper
capture = new CaptureHelper();
capture.ContextForEvents = WindowsFormsSynchronizationContext.Current;
capture.DeviceArrival += CaptureDeviceArrival;
capture.DeviceRemoval += CaptureDeviceRemoval;
capture.DecodedData += CaptureDecodedData;
labelStatus.Text = "no scanner connected";
string appId = "windows:com.mycompany.myapp";
string developerId = "520CE559-D74D-4447-9E65-0E35512A0344";
string appKey = "MC3CFQD76T2AE/Jus4JJ6nxZJyub3WBxXgIVAKglTx239tKjR+LNspa46Y9io2w5";
long result = await capture.OpenAsync(appId, developerId, appKey);
if (!SktErrors.SKTSUCCESS(result)) {
labelCaptureVersion.Text = "Unable to connect to Socket Mobile Companion (" + result + ")";
}
}
void CaptureDeviceRemoval(object sender, CaptureHelper.DeviceArgs e)
{
RemoveDeviceFromListBox(listBoxDevices, e.CaptureDevice);
}
void CaptureDeviceArrival(object sender, CaptureHelper.DeviceArgs e)
{
AddDeviceIntoListBox(listBoxDevices, e.CaptureDevice);
labelStatus.Text = e.CaptureDevice.GetDeviceInfo().Name;
}
async void CaptureDecodedData(object sender, CaptureHelper.DecodedDataArgs e)
{
textBoxDecodedData.Text = e.DecodedData.DataToUTF8String;
}
Note
The line capture.ContextForEvents = WindowsFormsSynchronizationContext.Current;
allows the application to handle the Capture Helper events directly in the UI Thread
context the UI can be directly updated.
If none of the event handlers updates the UI then this line can be removed.
Note
For Xamarin, if the UI has to be updated in the Capture event handlers and if
the System.Windows assembly is not used, it is probably best to use
RunOnUiThread()
and don’t specify any context for the events.
Note
For Xamarin, the websocket implementation is incomplete in the earlier version,
therefore it should be disabled by adding this line capture.DoNotUseWebSocket = true;
before calling the OpenAsync method.
Adding features to Capture Helper¶
Capture Helper is implemented as partial class. If your application needs a feature that is not implemented in Capture Helper, that feature can be added by creating a CaptureHelper partial class, copy-pasting a similar feature from the provided CaptureHelper, and modifying it to match your application needs.
Capture Helper with Debug Traces¶
If the application is compiled in Debug mode it is possible to activate the
traces from Capture Helper.
The application should pass a Capture Debug Console object that implements the
unique method void PrintLine(string message)
.
Here is sample code showing the details of this feature by first creating a
DebugConsole class (or whatever other name you pick) derived from
CaptureHelperDebug
as shown here:
#if DEBUG
class DebugConsole : CaptureHelperDebug
{
public void PrintLine(string message)
{
Debug.WriteLine(message);
}
}
#endif
Then after creating the Capture Helper instance this DebugConsole instance is passed to the Capture Helper instance as shown here:
public Form1()
{
InitializeComponent();
// initialize CaptureHelper
capture = new CaptureHelper();
#if DEBUG
capture.DebugConsole = new DebugConsole();
#endif
capture.ContextForEvents = WindowsFormsSynchronizationContext.Current;
capture.DeviceArrival += CaptureDeviceArrival;
capture.DeviceRemoval += CaptureDeviceRemoval;
capture.DeviceOwnershipChange += CaptureDeviceOwnershipChange;
capture.DecodedData += CaptureDecodedData;
capture.Errors += CaptureErrors;
capture.DevicePowerState += DevicePowerState;
capture.Terminate += Terminate;
...