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

2024-03-07

我在 Windows 8.1 上的 Visual Studio Professional 13 中使用 C#WDK http://msdn.microsoft.com/en-us/library/windows/hardware/ff547083(v=vs.85).aspx安装。

我需要编写一个使用自定义服务 UUID 与 BLE 设备交互的桌面应用程序。使用蓝牙通用属性配置文件 - 心率服务 http://code.msdn.microsoft.com/windowsapps/Bluetooth-Generic-5a99ef95MSDN 提供了示例项目,我能够编辑正在搜索的服务 UUID 并找到我的特定设备。

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

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

但是当创建一个Visual C# > Windows Desktop > *项目中,我找不到包含 Windows 8 运行时和BLE API http://msdn.microsoft.com/en-us/library/windows/apps/xaml/dn264587.aspx我需要访问。

当然,微软并没有短视到将 BLE API 限制为存储应用程序?如何创建/修改项目来开发利用 BLE API 的桌面和控制台应用程序?

到目前为止我所做的研究(和失败的尝试)已经排除了32英尺网 http://32feet.codeplex.com/因为该库目前不提供对蓝牙低能耗堆栈的支持。

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


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

使用 C#,您必须手动添加项目和运行时引用才能使其正常工作。这博客文章 http://www.hanselman.com/blog/HowToCallWinRTAPIsInWindows8FromCDesktopApplicationsWinRTDiagram.aspx详细介绍了它。简而言之,要让“核心”选项卡出现在项目设置中,您需要手动将其添加到您的 Visual Studio 项目中MSDN http://msdn.microsoft.com/en-us/library/hh708954(v=vs.110).aspx.

<PropertyGroup>
    <TargetPlatformVersion>8.0</TargetPlatformVersion>
</PropertyGroup>

然后手动添加对 System.Runtime.dll 和 System.Runtime.InteropServices.WindowsRuntime.dll 的引用。

顺便说一句,对于 C++,您可以利用 ABI 命名空间来调用 WinRT 函数(例如我在用于音频的 DirectXTK http://go.microsoft.com/fwlink/?LinkId=248929)或者您可以使用 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 或更早版本上运行。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在控制台应用程序中引用 Windows 8 运行时(特别是 BLE API)? 的相关文章

随机推荐

  • 如何通过 Mercurial 命令行获取所有关闭的分支?

    在命令行中 我可以通过以下方式获取没有闭合分支的所有头 hg heads 我还可以通过以下方式获取所有具有闭合分支的头 hg heads closed 但是 我如何通过命令行知道所有关闭的分支 RTM hg help revsets hg
  • Node.js:客户端模板与服务器端模板

    我已经尝试学习 Node js 几天了 但有一件事情我很困惑 JQuery 模板等客户端模板解决方案与 Jade for Node js 等服务器端解决方案之间有什么区别 各有什么用途 它们用在哪里 它们可以一起使用吗 如果有的话 有没有两
  • 使用“IN”命令将数组作为参数传递给 SQL 查询

    大家下午好 我有一个关于 SQL 查询的问题 是否可以使用数组作为使用 IN 命令的查询的参数 例如 int x 2 3 4 5 UPDATE table name set field 数据 WHERE field ID IN x 我问这个
  • Auth.net 捕获问题

    我在 auth net 上捕获交易的函数是 public function capture Varien Object payment amount if this gt isEnabled return parent capture pa
  • 带地址的 R 地理编码

    我有 32K 行地址 我必须为其查找长 纬度值 我正在使用找到的代码here http www storybench org geocode csv addresses r 我非常感谢这个人创造了它 但我有一个问题 我想对其进行编辑 以便如
  • pthread_create 的钩子

    是否有 在 glibc 2 5 及更新版本中 为 pthread create 定义钩子的方法 有很多二进制应用程序 我想编写一个动态库通过 LD PRELOAD 加载 我可以在 main 属性构造函数 的入口处添加钩子 但是如何强制我的代
  • 如何在Stream上短路reduce?

    假设我有一个布尔值流 并且我正在编写的归约操作是 或者 我能否以一种方式编写它 以便在以下情况下放弃至少某些元素的评估 true遇到的值是 我正在寻找一定程度的优化 也许如果它是并行流 不一定是完全优化 尽管后者会很棒 我怀疑你想要这种类型
  • 如何使新的 html 5 datalist 输入立即打开?

    问题很难理解 英语不是我的母语 我会尽力而为 所以新的html标签
  • 在 SDL Tridion 2011 发布期间提出“警告”状态

    我们希望实现一些功能 以便当由于某种原因在发布或解决过程中发生错误时 我们可以使用 try catch 块跳过它 但仍然希望通知用户某些内容被跳过 SDL Tridion 2011 发布队列可以按状态进行过滤 这些状态之一是 警告 是否可以
  • npmauditfix --force 改变了什么以及如何修复它?

    我试图npm install apn save并使用npm audit fix force 希望你知道自己在做什么 的信息让我意识到我不知道自己在做什么 之后我原本得到 node home ec2 user myapp bin www sy
  • P4 - 为客户更改工作空间

    我想使用 p4 命令行更改工作区客户端 但我不知道是否可能 您可以使用 p4workspace 命令创建 删除或编辑工作区 但我想使用 bat 方法更改当前工作区 示例 p4 c MyClient 更改工作空间 myNewWorkspace
  • Ubuntu 14.04:升级到 php7 并卸载 php5?

    我正在将基于 Ubuntu 14 04 的 docker 映像中的 php 版本升级到 7 0 我读了一些文章 给出了在安装 php7 0 时卸载 php5 的命令 这真的有必要吗 优缺点都有什么 添加 PHP 7 的新存储库 apt ge
  • 在 Django 中,如何在组添加或删除用户时获取信号?

    在 Django 管理中 我有时会向 现有 组添加或删除用户 当发生这种情况时 我希望能够运行一个函数 我只是使用标准的用户和组模型 我已经考虑过通过 m2m changed 使用信号来完成此操作 但似乎需要一个 Through 类 我认为
  • gdfs 到图表,反之亦然

    当我使用python的时候会发生以下情况osmnx如下 graph osmnx graph from polygon Data bbox gdf nodes gdf edges osmnx save load graph to gdfs g
  • lua:关于本地范围的模块导入

    有两个脚本文件 脚本如下 parent lua function scope local var abc require child end child lua print var 这样 child lua 将打印 nil 值 因为 Par
  • Android:将位图从本地存储加载到应用程序小部件(RemoteViews)

    到目前为止 我一直在将位图加载到我的RemoteViews直接使用remoteViews setImageViewBitmap 总体来说运行良好 但有几个用户遇到了问题 我认为是在加载非常大的位图时出现的 无论如何 我已经将位图缓存到本地存
  • 从 hdfs 读取 ocr 文件后令人难以置信地触发数据帧

    我在 Ambari 上使用 Spark 2 1 1 和 hadoop 2 6 时遇到问题 我首先在本地计算机上测试了我的代码 单节点 本地文件 一切都按预期工作 from pyspark sql import SparkSession sp
  • 如何禁用 VS-Code GCC 编译器的警告? (不使用#pragma)

    我正在使用 C C intellisense gcc arm 开发 VS Code 当我编译时 VS Code 向我显示了数百个这样的警告 Conversion from int to u16 t aka short unsigned in
  • 如何在 Spree 2.x / Rails 4 中覆盖 Product_url 以使 SEO 更友好?

    我希望我的产品网址如下所示 product name here p 代替 product product name here 我怎样才能实现这个目标 经过大量研究后我明白了 此过程有两个步骤 首先是创建与新产品路线相匹配的路线 因此 进入你
  • 如何在控制台应用程序中引用 Windows 8 运行时(特别是 BLE API)?

    我在 Windows 8 1 上的 Visual Studio Professional 13 中使用 C WDK http msdn microsoft com en us library windows hardware ff54708