我在安装了WDK的 Windows 8.1上使用Visual Studio Professional 13中的C#。
我需要编写一个使用自定义服务UUID与BLE设备交互的桌面应用程序。 使用蓝牙通用属性configuration文件 –从MSDN提供的心率服务示例项目,我可以编辑正在search的服务UUID并find我的特定设备。
但是,示例项目是Windowsapp store(Metro),我需要一个控制台应用程序。
当我创build一个types为Visual C# > Store App > Windows App
的新项目时,Windows 8 SDK将自动包含在项目中。
但是,当创build一个Visual C# > Windows Desktop > *
项目,我找不到一种方法来包括Windows 8运行时间和我需要访问的BLE API 。
当然,微软并没有把BLE API限制到商店应用程序那么短视。 如何创build/修改他们的项目来开发利用BLE API的桌面和控制台应用程序?
迄今为止我所做的研究(和失败的尝试)已经排除了32feet.net,因为图书馆目前不提供对蓝牙低能量堆栈的支持。
但是,如果有另一个提供BLE支持的第三方库(最好是开放源代码,或者至less有一个试用版),我将会公开使用它来代替Windows 8 Runtime。
可以从Windows 8.x上的Win32桌面应用程序调用WinRT API,但这不是一个经过充分测试或者更重要的记录良好的情况。
使用C#,您必须手动添加项目和运行时引用才能使其工作。 这篇博客文章详细介绍了它。 简而言之,要使“核心”选项卡出现在项目设置中,您需要手动将其添加到每个MSDN的 Visual Studio项目中。
<PropertyGroup> <TargetPlatformVersion>8.0</TargetPlatformVersion> </PropertyGroup>
然后手动添加对System.Runtime.dll和System.Runtime.InteropServices.WindowsRuntime.dll的引用。
顺便说一下,对于C ++,可以使用ABI命名空间来调用WinRT函数(例如我在DirectXTK for Audio中的一种情况下),也可以使用C ++ / CX扩展。
#if defined(__cplusplus_winrt) // Enumerating with WinRT using C++/CX (Windows Store apps) using Windows::Devices::Enumeration::DeviceClass; using Windows::Devices::Enumeration::DeviceInformation; using Windows::Devices::Enumeration::DeviceInformationCollection; auto operation = DeviceInformation::FindAllAsync(DeviceClass::AudioRender); while (operation->Status != Windows::Foundation::AsyncStatus::Completed) ; DeviceInformationCollection^ devices = operation->GetResults(); for (unsigned i = 0; i < devices->Size; ++i) { using Windows::Devices::Enumeration::DeviceInformation; DeviceInformation^ d = devices->GetAt(i); ... } #else // Enumerating with WinRT using WRL (Win32 desktop app for Windows 8.x) using namespace Microsoft::WRL; using namespace Microsoft::WRL::Wrappers; using namespace ABI::Windows::Foundation; using namespace ABI::Windows::Foundation::Collections; using namespace ABI::Windows::Devices::Enumeration; RoInitializeWrapper initialize(RO_INIT_MULTITHREADED); HRESULT hr = initialize; ThrowIfFailed( hr ); Microsoft::WRL::ComPtr<IDeviceInformationStatics> diFactory; hr = ABI::Windows::Foundation::GetActivationFactory( HStringReference(RuntimeClass_Windows_Devices_Enumeration_DeviceInformation).Get(), &diFactory ); ThrowIfFailed( hr ); Event findCompleted( CreateEventEx( nullptr, nullptr, CREATE_EVENT_MANUAL_RESET, WRITE_OWNER | EVENT_ALL_ACCESS ) ); if ( !findCompleted.IsValid() ) throw std::exception( "CreateEventEx" ); auto callback = Callback<IAsyncOperationCompletedHandler<DeviceInformationCollection*>>( [&findCompleted,list]( IAsyncOperation<DeviceInformationCollection*>* aDevices, AsyncStatus status ) -> HRESULT { UNREFERENCED_PARAMETER(aDevices); UNREFERENCED_PARAMETER(status); SetEvent( findCompleted.Get() ); return S_OK; }); ComPtr<IAsyncOperation<DeviceInformationCollection*>> operation; hr = diFactory->FindAllAsyncDeviceClass( DeviceClass_AudioRender, operation.GetAddressOf() ); ThrowIfFailed( hr ); operation->put_Completed( callback.Get() ); (void)WaitForSingleObjectEx( findCompleted.Get(), INFINITE, FALSE ); ComPtr<IVectorView<DeviceInformation*>> devices; operation->GetResults( devices.GetAddressOf() ); unsigned int count = 0; hr = devices->get_Size( &count ); ThrowIfFailed( hr ); if ( !count ) return list; for( unsigned int j = 0; j < count; ++j ) { ComPtr<IDeviceInformation> deviceInfo; hr = devices->GetAt( j, deviceInfo.GetAddressOf() ); if ( SUCCEEDED(hr) ) { HString id; deviceInfo->get_Id( id.GetAddressOf() ); HString name; deviceInfo->get_Name( name.GetAddressOf() ); ... } } #endif
这当然是只与Windows 8.0或更高版本兼容的代码,并且不能在Windows 7或更低版本上运行。
创建一个可移植的类库,并把所有BLE代码放在那里,然后在桌面/控制台应用程序中引用这个库。