我正在尝试获取一个Windows::Devices::Usb::UsbDevice引用我所拥有的特定USB设备的对象,以便将其传递给第三方插件.由于项目限制,我无法使用C++/CX扩展名.
在查看了无数的线程,答案和引用之后,我想出了一个初始实现,它可以在我需要的WinRT类上调用静态方法.唯一的问题是,即使没有调用导致失败HRESULT,最后一次调用FromIdAsync也不起作用,给我me ERROR_INVALID_HANDLE(6)作为结果GetLastError().
简单地读取错误名称会让我误认为是获取设备的ID,因为这是我传递该调用的唯一句柄,但我尝试传递一个常量字符串(我知道这是正确的)并且它产生了相同的结果.
这就是我调用FromIdAsync*的方式:
// Retrieves static methods for UsbDevice class
ComPtr<IUsbDeviceStatics> usbDevSt;
hr = GetActivationFactory(
HStringReference(RuntimeClass_Windows_Devices_Usb_UsbDevice).Get(),
&usbDevSt
);
// Creates an event to work as a 'semaphore', for waiting for the 'FromIdAsync'
// call to be completed
Event openEvent(CreateEventEx(
nullptr,
nullptr,
CREATE_EVENT_MANUAL_RESET,
WRITE_OWNER | EVENT_ALL_ACCESS
));
if (!openEvent.IsValid()) return nullptr;
// Setups a callback for when the device enumeration is done
auto asyncOpenCb …Run Code Online (Sandbox Code Playgroud) 我正在尝试使WinRT库不使用CX扩展名。我需要获取程序包的名称,漫游数据文件夹等。我写了一些包装器,但是当我将此库链接到可执行项目时,出现链接器错误
error LNK2019: unresolved external symbol _WindowsCreateStringReference@16 referenced in function "private: void __thiscall Microsoft::WRL::Wrappers::HStringReference::CreateReference(wchar_t const *,unsigned int,unsigned int)" (?CreateReference@HStringReference@Wrappers@WRL@Microsoft@@AAEXPB_WII@Z)
error LNK2019: unresolved external symbol _WindowsDeleteString@4 referenced in function "public: __thiscall Microsoft::WRL::Wrappers::HStringReference::~HStringReference(void)" (??1HStringReference@Wrappers@WRL@Microsoft@@QAE@XZ)
error LNK2019: unresolved external symbol _WindowsGetStringRawBuffer@8 referenced in function "long __cdecl aponialib::winrt::GetFullName(class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> > &)" (?GetFullName@winrt@aponialib@@YAJAAV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@@Z)
error LNK2019: unresolved external symbol __imp__RoGetActivationFactory@12 referenced in function "long __cdecl Windows::Foundation::GetActivationFactory<struct ABI::Windows::Storage::IApplicationDataStatics>(struct HSTRING__ *,struct ABI::Windows::Storage::IApplicationDataStatics * *)" (??$GetActivationFactory@UIApplicationDataStatics@Storage@Windows@ABI@@@Foundation@Windows@@YAJPAUHSTRING__@@PAPAUIApplicationDataStatics@Storage@1ABI@@@Z)
Run Code Online (Sandbox Code Playgroud)
这是包裹名称包装
// including in .h
#include <windows.h>
#include <string> …Run Code Online (Sandbox Code Playgroud) 我按照这里的示例:http://msdn.microsoft.com/en-us/library/vstudio/jj822931.aspx使用Windows运行时模板库(WRL)创建进程内经典COM DLL.我也可以修改代码来运行DLL作为COM代理(包含在DllHost.exe中).
但是,我找不到使用WRL创建进程外COM EXE的方法.这里有一个使用准系统COM API的简单示例:http://www.codeproject.com/Articles/3173/A-simple-yet-debuggable-COM-skeleton-code,但我想知道如何利用WRL简化了这一点.
谢谢.
我只想知道ComPtr和之间的确切区别CComPtr,以及是否ComPtr::As()类似于CComPtr::QueryInterface()?我阅读了两者的文档,但是这个问题没有明确的答案......
我公司有许多用vb6编写的旧项目。我们有一些用ATL / C ++编写的可重用软件组件。现在,我们正在考虑使用UWP重写我们的应用程序,但是UWP应用程序似乎不支持旧的COM技术。我正在研究是否有一种方法来实现还支持UWP的COM对象。我知道将我们的旧组件移植到UWP组件肯定会起作用。但是我们不想维护两个版本的通用组件,因为我们已经发布了许多旧软件,但仍提供软件支持。其中一些软件已被我们的客户使用超过10年。无法升级我们提供的所有软件。
我提出了几种可能的解决方案:
桌面桥
我发现了一个短语“ Packaged COM”,UWP应用程序可以通过Desktop Bridge使用该短语。本文是对Desktop Bridge的COM服务器和OLE文档的支持,给出了一个从UWP应用程序调用exe COM服务器的示例。如果它也支持InProcessServer,这似乎是一个很好的解决方案。我确实发现了一些可疑的InProcessServer,但事实证明它是针对WinRT组件的。
我还尝试将COM引用添加到UWP项目。该代码可以成功引用COM对象。但是,它在运行时不起作用。UWP应用具有自己的注册表配置单元,因此不会加载已注册到系统注册表的COM对象。我的想法是,如果将注册信息添加到UWP应用程序的私有配置单元中,并将COM dll与该应用程序一起打包,则可能会起作用。只是找不到任何例子。
ATL / COM
由于我们已经将bussinuess逻辑实现到COM对象中。最可行的解决方案是升级我们的COM对象以支持UWP应用程序。WinRT组件仍然使用COM技术,但实现了新接口IInspectable,我假设如果旧的基于ATL的COM对象实现IInspectable接口,则可以对其进行修改以支持UWP的调用约定。我只是没有任何线索可以做到这一点。
WRL
我找到了MSDN文章“ 如何:使用WRL创建经典COM组件”,谈论了使用WRL项目模板来实现可在Win32应用程序和UWP应用程序中使用的COM对象类。
它说:
除了将其用于通用Windows平台(UWP)应用程序外,还可以使用Windows运行时C ++模板库(WRL)创建基本的经典COM组件以供桌面应用程序使用。
但是我很快意识到Microsoft不再支持WRL项目模板。我在网上可以找到的项目模板的所有下载链接都不再可用。
C ++ / WinRT
这项技术似乎是WRL的继承者。似乎很有希望,但不幸的是尚未发布。
为了澄清@Peter Torr的一些事情:
(1)您是否希望您的应用程序/ COM对象是“纯” UWP(在所有设备上运行),还是可以使用仅限桌面的fullTrust UWP(又名Desktop Bridge)?(2)COM对象仅用于附带它们的应用程序,还是应该由其他应用程序使用?
我公司使用Windows平台提供基于PC的工业自动化服务(包括硬件和软件)。因此答案是肯定的,我们对fullTrust UWP感到满意。我们的产品只能在台式机上运行。我们只想拥抱新技术并利用UWP的出色UI框架。
COM对象既适用于新应用程序(UWP),也适用于旧软件(某些基于vb6)。我们很高兴将COM对象与UWP应用程序打包在一起,并使用系统注册的COM作为旧软件,只要这些COM对象是相同的(从相同的代码库构建)即可。
我一直在C++中使用C#,C++/CX和WRL来试验WinRT组件.到目前为止,我设法做了我尝试过的所有事情,即使与COM相比,有些东西已经改变,要么让人感到困惑,要么令人沮丧.
我正在尝试的最后一件事,到目前为止,我做不到的是COM的基本架构模式.我只是想创建一个WRL组件的实例,而不是在使用该组件的项目中引用DLL.据我记得这是COM的基本行为,提供COM的CoClass的GUID,使用程序只知道接口,CoCreateInstance将动态加载COM并创建附加到您请求的接口的实例.
我无法找到如何用WRL做到这一点.我已经定义了一些简单的接口,我甚至无法在注册表中找到它们.但是,由于COM可以在没有注册表的情况下使用对象,并且现在存在窗口元数据,我认为这就是原因.
有人在那里知道这不是WinRT的限制(这会使它成为一个非常糟糕的架构......)或者如果有可能如何实现与WRL的后期绑定.
为了说清楚,在调用程序中我只想提供接口的信息(这可以是.h)然后我需要能够使用其GUID或名字对象名称创建WinRT组件的实例.这是我在C++/COM,C#和Java中使用的体系结构模式,因为您可以编写应用程序并支持新功能而无需触及应用程序的某一行,甚至无需重新编译它.
谢谢O. Rouit
我在更新后尝试像往常一样编译我的项目(15.8.0).我将showincludes设置为yes来确定错误的起源,但它是所有系统代码.从stdafx.cpp开始,它会遍历所有包含和错误:
Run Code Online (Sandbox Code Playgroud)1>Note: including file: C:\Program Files (x86)\Windows Kits\10\Include\10.0.17134.0\shared\pshpack8.h 1>Note: including file: C:\Program Files (x86)\Windows Kits\10\Include\10.0.17134.0\shared\poppack.h 1>Note: including file: C:\Program Files (x86)\Windows Kits\10\Include\10.0.17134.0\shared\pshpack8.h 1>Note: including file: C:\Program Files (x86)\Windows Kits\10\Include\10.0.17134.0\shared\poppack.h 1>Note: including file: C:\Program Files (x86)\Windows Kits\10\Include\10.0.17134.0\winrt\wrl\event.h 1>Note: including file: C:\Program Files (x86)\Windows Kits\10\Include\10.0.17134.0\winrt\eventtoken.h 1>Note: including file: C:\Program Files (x86)\Windows Kits\10\Include\10.0.17134.0\shared\pshpack8.h 1>c:\program files (x86)\windows kits\10\include\10.0.17134.0\winrt\wrl\event.h(316): error C7510: 'Callback': use of dependent template name must be prefixed with 'template' 1>c:\program files (x86)\windows kits\10\include\10.0.17134.0\winrt\wrl\event.h(324): error C7510: 'Callback': use of dependent template name must …
当我使用WRL创建winrt组件时,问题是我只能使用ABI::Windows::xxx命名空间,而且我不能Windows::UI::Xaml::Media::Imaging在WRL中使用命名空间.
那么,如何创建内置winrt组件作为返回值?
// idl
import "inspectable.idl";
import "Windows.Foundation.idl";
import "Windows.UI.Xaml.Media.Imaging.idl";
namespace Decoder
{
interface IPhotoDecoder;
runtimeclass PhotoDecoder;
interface IPhotoDecoder : IInspectable
{
HRESULT Decode([in] int width, [in] int height, [out, retval] Windows.UI.Xaml.Media.Imaging.BitmapImage **ppBitmapImage);
}
[version(COMPONENT_VERSION), activatable(COMPONENT_VERSION)]
runtimeclass PhotoDecoder
{
[default] interface IPhotoDecoder;
}
}
// cpp
using namespace Microsoft::WRL;
using namespace Windows::Foundation;
using namespace ABI::Windows::UI::Xaml::Media::Imaging;
namespace ABI
{
namespace Decoder
{
class PhotoDecoder: public RuntimeClass<IPhotoDecoder>
{
InspectableClass(L"Decoder.PhotoDecoder", BaseTrust)
public:
PhotoDecoder()
{
}
HRESULT __stdcall Decode(_In_ int …Run Code Online (Sandbox Code Playgroud) 我可以在C++中使用WRL库来代替ATL来编写COM组件吗?如果是的话,我是否可以在较旧的桌面Windows系统上使用它,比如Windows XP?
我很确定第一个问题的答案是肯定的,因为我在MSDN上找到了这个教程:
http://msdn.microsoft.com/en-us/library/jj822931.aspx
但是非Windows 8系统呢?