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
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.
8.0
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 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>(
[&findCompleted,list]( IAsyncOperation* aDevices, AsyncStatus status ) -> HRESULT
{
UNREFERENCED_PARAMETER(aDevices);
UNREFERENCED_PARAMETER(status);
SetEvent( findCompleted.Get() );
return S_OK;
});
ComPtr> operation;
hr = diFactory->FindAllAsyncDeviceClass( DeviceClass_AudioRender, operation.GetAddressOf() );
ThrowIfFailed( hr );
operation->put_Completed( callback.Get() );
(void)WaitForSingleObjectEx( findCompleted.Get(), INFINITE, FALSE );
ComPtr> 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 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.