我正在开发一款移动应用程序(平板电脑上的C#/ WPF),可打印到连接蓝牙的打印机。现在我只是关闭打印作业,如果打印机不存在,打印机子系统会向用户报告错误。我没有用蓝牙编程,只使用PrintDialog()。
我想修改此过程以首先检测打印机 - 如果它不可用,那么我将只存储文档而不打印。我可以通过代码检测蓝牙设备是否连接/活动/可用吗?
如果我查看控制面板下蓝牙面板中的设备,它似乎没有任何反映该设备是否可用的状态,所以可能这是不可能的。
我假设打印机已经在Windows中进行了设置和配置 - 我需要做的就是检测它是否实际存在于给定的时间点。
答案 0 :(得分:1)
也许使用32feet.NET库(我是维护者)并在提交作业之前检查打印机是否存在。您需要知道打印机的蓝牙地址;可以从系统中获得,或者你可能总是知道它。
MSFT蓝牙堆栈上的发现始终会返回范围内的所有已知设备:-(但我们可以使用其他方法来检测设备的存在/不存在。也许在其BeginGetServiceRecords表单中使用BluetoothDeviceInfo.GetServiceRecords。例如(类似)未经测试/编译):
bool IsPresent(BluetoothAddress addr) // address from config somehow
{
BluetoothDeviceInfo bdi = new BluetoothDeviceInfo(addr);
if (bdi.Connected) {
return true;
}
Guid arbitraryClass = BluetoothService.Headset;
AsyncResult<bool> ourAr = new AsyncResult<bool>(); // Jeffrey Richter's impl
IAsyncResult ar = bdi.BeginGetService(arbitraryClass, IsPresent_GsrCallback, ourAr);
bool signalled = ourAr.AsyncWaitHandle.WaitOne(Timeout);
if (!signalled) {
return false; // Taken too long, so not in range
} else {
return ourAr.Result;
}
}
void IsPresent_GsrCallback(IAsyncResult ar)
{
AsyncResult<bool> ourAr = (AsyncResult<bool>)ar.AsyncState;
const bool IsInRange = true;
const bool completedSyncFalse = true;
try {
bdi.EndGetServiceResult(ar);
ourAr.SetAsCompleted(IsInRange, completedSyncFalse);
} catch {
// If this returns quickly, then it is in range and
// if slowly then out of range but caller will have
// moved on by then... So set true in both cases...
// TODO check what error codes we get here. SocketException(10108) iirc
ourAr.SetAsCompleted(IsInrange, completedSyncFalse);
}
}