可以从 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 或更早版本上运行。