gpt4 book ai didi

c# - 如何在控制台应用程序中引用 Windows 8 运行时(特别是 BLE API)?

转载 作者:可可西里 更新时间:2023-11-01 14:49:56 27 4
gpt4 key购买 nike

我在 Windows 8.1 的 Visual Studio Professional 13 中使用 C# 和 WDK 已安装。

我需要编写一个使用自定义服务 UUID 与 BLE 设备交互的桌面应用程序。使用 Bluetooth Generic Attribute Profile - Heart Rate Service 示例项目可从 MSDN 获得,我能够编辑正在搜索的服务 UUID 并找到我的特定设备。

但是,示例项目是一个 Windows Store (Metro) 应用程序,我需要一个控制台应用程序。

当我创建类型为 Visual C# > Store App > Windows App 的新项目时,Windows 8 SDK 会自动包含在该项目中。

但是在创建 Visual C# > Windows Desktop > * 项目时,我找不到包含 Windows 8 运行时和 BLE API 的方法 我需要访问。

当然,Microsoft 并没有短视到将 BLE API 限制在商店应用程序上?如何创建/修改他们的项目以开发利用 BLE API 的桌面和控制台应用程序?

我到目前为止所做的研究(和失败的尝试)已经排除了 32feet.net 因为该库目前不提供对蓝牙低功耗堆栈的支持。

但是,如果有另一个提供 BLE 支持的第 3 方库(最好是开源的,或者至少有一个试用版),我愿意使用它来代替 Windows 8 运行时。

最佳答案

可以从 Windows 8.x 上的 Win32 桌面应用程序调用 WinRT API,但这不是一个经过充分测试或更重要的是没有很好记录的场景。

使用 C#,您必须手动添加项目和运行时引用才能使其正常工作。这blog post详细介绍了它。简而言之,要让“核心”选项卡出现在您的项目设置中,您需要根据 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 或更早版本上运行。

关于c# - 如何在控制台应用程序中引用 Windows 8 运行时(特别是 BLE API)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24843102/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com