Windows 如何知道我的MFC应用程序是否使用COM/OLE?

Windows 如何知道我的MFC应用程序是否使用COM/OLE?,windows,mfc,Windows,Mfc,我从Win7到Win10,最近打开一个文件时遇到了“不正确的参数错误”。 该错误非常罕见且随机发生。 没有提供进一步的信息或调用堆栈信息。我在MFC代码中做了深入的搜索。DocManager打开文档,然后调用CDocument::SetPathName(..,TRUE)将当前文件也添加到最近使用的文件列表中 看起来这个函数现在使用的是OLE/COM函数 void CRecentFileList::Add(LPCTSTR lpszPathName, LPCTSTR lpszAppID) { :

我从Win7到Win10,最近打开一个文件时遇到了“不正确的参数错误”。
该错误非常罕见且随机发生。
没有提供进一步的信息或调用堆栈信息。我在MFC代码中做了深入的搜索。DocManager打开文档,然后调用
CDocument::SetPathName(..,TRUE)
将当前文件也添加到最近使用的文件列表中

看起来这个函数现在使用的是OLE/COM函数

void CRecentFileList::Add(LPCTSTR lpszPathName, LPCTSTR lpszAppID)
{
  :
  :
  Add(lpszPathName);

  HRESULT hr = S_OK;
  CComPtr<IShellItem> psi = NULL;

  hr = _AfxSHCreateItemFromParsingName(lpszPathName, NULL, IID_IShellItem, reinterpret_cast<void**>(&psi));
  ENSURE(SUCCEEDED(hr));   // Remark Tom: This throws an AfxInvalidException()
 
}
void CRecentFileList::Add(LPCTSTR lpszPathName,LPCTSTR lpszAppID)
{
:
:
添加(lpszPathName);
HRESULT hr=S_正常;
CComPtr psi=NULL;
hr=_AfxSHCreateItemFromParsingName(lpszPathName,NULL,IID_IShellItem,reinterpret_cast(&psi));
确保(成功(hr));//备注汤姆:这会抛出一个AfxInvalidException()
}
hr错误代码为-2147221008,这意味着未调用
CoInitialize

我很惊讶,因为我从未使用过COM/OLE的东西

要克服这个错误,我必须在
InitInstance
中添加
AfxOleInit()

我的问题是,如何提前知道我的应用程序是否需要使用OLE/COM

另外一个问题,如果我在应用程序中使用COM/OLE,我会有什么缺点吗。(内存和速度)

我的问题是,如何提前知道我的应用程序是否需要使用OLE/COM

MFC应用程序应该总是初始化OLE/COM,特别是使用STA(单线程单元)的并发模型。这是在向导生成的模板中自动完成的,否则必须在用户代码中显式完成。从文件中:

MFC应用程序必须初始化为单线程单元(STA)

如果在InitInstance覆盖中调用coinitializex,请指定COINIT_APARTMENTTHREADED(而不是COINIT_多线程)

将OLE/COM始终初始化为STA也可以避免@IInspectable在注释中提及

我的问题是,如何提前知道我的应用程序是否需要使用OLE/COM

MFC应用程序应该总是初始化OLE/COM,特别是使用STA(单线程单元)的并发模型。这是在向导生成的模板中自动完成的,否则必须在用户代码中显式完成。从文件中:

MFC应用程序必须初始化为单线程单元(STA)

如果在InitInstance覆盖中调用coinitializex,请指定COINIT_APARTMENTTHREADED(而不是COINIT_多线程)


让OLE/COM始终初始化为STA也避免了@IInspectable在评论中提到。

由于有太多的Windows API表面通过COM公开,因此可以很好地猜测,任何非平凡的Windows应用程序都会在某个时候使用COM。将线程初始化到COM单元不是免费的。一旦完成,就不会有任何运行时开销。为COM注册线程不太可能出现任何明显的性能下降。请注意,COM是按线程初始化的。
InitInstance
中的一个初始化调用只会注册您的UI线程。注意:您的MFC应用程序可能一直使用COM,但即使它应该使用COM,也没有失败(有关详细信息,请参阅)。Windows 10中可能发生了一些变化。由于有如此多的Windows API表面是通过COM公开的,所以很有可能任何非平凡的Windows应用程序都会在某个时候使用COM。将线程初始化到COM单元不是免费的。一旦完成,就不会有任何运行时开销。为COM注册线程不太可能出现任何明显的性能下降。请注意,COM是按线程初始化的。
InitInstance
中的一个初始化调用只会注册您的UI线程。注意:您的MFC应用程序可能一直使用COM,但即使它应该使用COM,也没有失败(有关详细信息,请参阅)。也许Windows 10中发生了一些变化。