1

我正在开发一个打印到蓝牙连接打印机的移动应用程序(平板电脑上的 C#/WPF)。现在我只是启动打印作业,如果打印机不存在,打印机子系统会向用户报告错误。我没有以编程方式使用蓝牙做任何事情,只是使用 PrintDialog()。

我想修改此过程以首先检测打印机 - 如果它不可用,那么我将只存储文档而不打印。有没有办法让我检测蓝牙设备是否已连接/活动/可用?

如果我在控制面板下的蓝牙面板中查看设备,它似乎没有任何反映设备是否可用的状态,所以这可能是不可能的。

我假设打印机已经在 Windows 中设置和配置 - 我需要做的就是检测它是否真的存在于给定的时间点。

4

1 回答 1

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);
    }
}
于 2009-07-03T13:54:06.920 回答