如何使用System.__ComObject?Xamarin.Forms HoneyWell扫描器UWP开发咨询
System.__ComObject in Your HoneyWell Scanner UWP Implementation Hey there! Let's walk through how to work with System.__ComObject when using the PointOfService BarcodeScanner API in your Xamarin.Forms UWP project. This usually pops up when interacting with COM-based WinRT APIs, and it's easy to resolve with a few key steps.
First, Understand Why System.__ComObject Appears
The PointOfService APIs (like BarcodeScanner) are built on COM under the hood. When .NET interacts with these COM objects, it wraps them in the generic System.__ComObject type by default. You can't call BarcodeScanner methods or subscribe to its events directly on this wrapper—you need to convert it to the specific WinRT interface type first.
Step 1: Convert the COM Object to BarcodeScanner
Use the As<T>() extension method (from the System.Runtime.InteropServices.WindowsRuntime namespace) to safely cast the __ComObject to a BarcodeScanner instance. Here's how that looks in your ScannerService implementation:
using System.Runtime.InteropServices.WindowsRuntime; using Windows.Devices.PointOfService; public class ScannerService : IScannerService, IDisposable { private BarcodeScanner _barcodeScanner; private ClaimedBarcodeScanner _claimedScanner; public event EventHandler<string> OnScan; public async Task InitializeScannerAsync() { // Get the default scanner (returns a __ComObject initially) var scannerComObject = await BarcodeScanner.GetDefaultAsync(); if (scannerComObject != null) { // Convert to BarcodeScanner type _barcodeScanner = scannerComObject.As<BarcodeScanner>(); // Claim and enable the scanner for use _claimedScanner = await _barcodeScanner.ClaimScannerAsync(); _claimedScanner.IsDecodeDataEnabled = true; _claimedScanner.DataReceived += OnBarcodeDataReceived; await _claimedScanner.EnableAsync(); } } private void OnBarcodeDataReceived(ClaimedBarcodeScanner sender, BarcodeScannerDataReceivedEventArgs args) { // Convert raw scanned data to a readable string string scannedText = args.Report.ScanDataLabel; // Raise your custom OnScan event to notify the shared project OnScan?.Invoke(this, scannedText); } // Clean up COM resources to avoid memory leaks public void Dispose() { if (_claimedScanner != null) { _claimedScanner.DataReceived -= OnBarcodeDataReceived; _claimedScanner.ReleaseDeviceAsync().AsTask().Wait(); _claimedScanner.Dispose(); } _barcodeScanner?.Dispose(); } }
Key Notes to Avoid Issues
- Always convert first: Never try to call
BarcodeScannermethods directly on the__ComObject—this will throw anInvalidCastException. - Include the right namespace: Make sure you have
using System.Runtime.InteropServices.WindowsRuntime;to access theAs<T>()extension method. - Proper resource cleanup: COM objects require explicit disposal to prevent memory leaks. Implement
IDisposablein yourScannerServiceand release the scanner when your app closes or the service is no longer needed.
What If You're Targeting the HoneyWell Scanner Specifically?
If you're using a device selector to target your HoneyWell scanner instead of using GetDefaultAsync(), the same conversion logic applies. For example:
string selector = BarcodeScanner.GetDeviceSelector(); var devices = await DeviceInformation.FindAllAsync(selector); foreach (var device in devices) { // Filter for HoneyWell device if needed (check device.Name) var scannerComObject = await BarcodeScanner.FromIdAsync(device.Id); var barcodeScanner = scannerComObject.As<BarcodeScanner>(); // Initialize the scanner as shown earlier }
That's all! By converting the System.__ComObject to the concrete BarcodeScanner type, you'll be able to use all the API's features seamlessly in your Xamarin.Forms UWP app.
内容的提问来源于stack exchange,提问作者SEG.Veenstra

