How can I reference the Windows 8 Runtime (specifically BLE API) in a console application?

后端 未结 2 845
时光说笑
时光说笑 2021-02-06 17:20

I am using C# in Visual Studio Professional 13 on Windows 8.1 with the WDK installed.

I need to write a desktop application that interacts with a BLE de

相关标签:
2条回答
  • 2021-02-06 18:06

    It is possible to call WinRT APIs from Win32 desktop apps on Windows 8.x, but this is not a well-tested or more importantly well-documented scenario.

    With C#, you have to manually add the project and runtimes references to get this to work. This blog post covers it in detail. In short, to get the "Core" tab to appear in your project settings you need to manually add this to your Visual Studio project per MSDN.

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

    Then manually add a reference to both System.Runtime.dll and System.Runtime.InteropServices.WindowsRuntime.dll.

    BTW, for C++, you can make use of ABI namespaces to call WinRT functions (such as I'm doing in one case in DirectXTK for Audio) or you can use C++/CX extensions.

    #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 
    

    This of course is code that is only compatible with Windows 8.0 or later and will not run on Windows 7 or earlier.

    0 讨论(0)
  • 2021-02-06 18:10

    Create a Portable Class Library and put all your BLE code there then reference the library in your desktop/console application.

    0 讨论(0)
提交回复
热议问题