【发布时间】:2020-09-27 10:14:29
【问题描述】:
根据我是否链接到特定库,Windows API 的行为似乎有所不同。不幸的是,它是一个相当大的库,很难追踪问题,我不知道从哪里开始。
我可以为多个 API 重现此行为。例如,我使用基于 COM 的 shell API 来确定特定文件扩展名的“打开方式”应用程序。
CComPtr<IEnumAssocHandlers> enumerator;
HRESULT hr = SHAssocEnumHandlers(L".jpg", ASSOC_FILTER_RECOMMENDED, &enumerator);
for (CComPtr<IAssocHandler> handler; enumerator->Next(1, &handler, nullptr) == S_OK; handler.Release()) {
CComHeapPtr<wchar_t> wAppName;
handler->GetName(&wAppName);
std::wcout << std::wstring(wAppName) << std::endl;
}
这在不执行任何其他操作的测试应用程序中完美运行。如果我链接到上述库,它会停止工作,而不是 UWP 应用程序条目,它只会打印 TWINUI。
实际上打开应用程序然后使用IAssocHandler::Invoke 的行为也不同,在 Adobe Photoshop 的情况下,它会令人惊讶地让用户退出 Adobe 帐户(这始终是可重现的 - 也许由于不同的上下文而发挥了一些许可保护作用?)。
我过去遇到的另一个例子是 WIC(Windows Imaging Component)API,也是基于 COM 的,它返回有关编解码器不可用的错误(在最小测试中可用)。
所以问题是:是否存在可能导致这些问题的编译器标志或宏? (例如 WinSDK 版本控制)
我还能寻找什么?
提前致以诚挚的问候和感谢
【问题讨论】:
-
没有“让 COM 做不同的事情” 编译器开关或预处理器宏。你将不得不产生一个minimal reproducible example。
-
可能是其他库初始化 COM 的方式与您的程序不同。
-
你用什么调用来初始化 COM?
-
我无法生成一个最小的可重现示例,因为库太大而不能轻易丢弃东西。这就是我寻找线索的原因。另一个库没有使用 COM,在我的应用程序中我使用
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);来初始化 COM。此外,我的应用程序中的所有 API 调用都发生在应用程序(而不是库)专用的线程中。
标签: c++ windows winapi visual-c++ com