When is calling CoInitialize required for a Windows console application
从https://docs.microsoft.com/zh-cn/windows/desktop/shell/folder-info#determining-an-objects-parent-folder派生的以下代码在通过Visual Studio编译和运行时可以按预期工作 2017年:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | #include"stdafx.h" #include <shlobj.h> #include <shlwapi.h> #include <objbase.h> #pragma comment(lib,"shlwapi") int main() { IShellFolder *psfParent = NULL; LPITEMIDLIST pidlSystem = NULL; LPCITEMIDLIST pidlRelative = NULL; STRRET strDispName; TCHAR szDisplayName[MAX_PATH]; HRESULT hr; hr = SHGetFolderLocation(NULL, CSIDL_SYSTEM, NULL, NULL, &pidlSystem); hr = SHBindToParent(pidlSystem, IID_IShellFolder, (void **)&psfParent, &pidlRelative); if (SUCCEEDED(hr)) { hr = psfParent->GetDisplayNameOf(pidlRelative, SHGDN_NORMAL, &strDispName); hr = StrRetToBuf(&strDispName, pidlSystem, szDisplayName, sizeof(szDisplayName)); _tprintf(_T("%s\ "), szDisplayName); } psfParent->Release(); CoTaskMemFree(pidlSystem); Sleep(5000); return 0; } |
但是,如果将
1 2 3 | onecore\\com\\combase\\objact\\objact.cxx(812)\\combase.dll!74EA3270: (caller: 74EA201B) ReturnHr(1) tid(d4c) 800401F0 CoInitialize has not been called. onecoreuap\\shell\\windows.storage\ egfldr.cpp(1260)\\windows.storage.dll!76FE4FA3: (caller: 76E9F7EE) ReturnHr(1) tid(d4c) 80040111 ClassFactory cannot supply requested class |
在对
为什么在一种情况下需要调用CoInitialize,而在另一种情况下则不需要?
同样,似乎应该始终调用CoInitialize,但有趣的是示例代码没有调用它。 我很好奇为什么会这样。 我无法按原样编译示例代码-找不到
通常,应该在创建从
为什么它与
Windows 95外壳程序可以运行而无需加载COM / OLE。为此,它提供了自己的mini-COM实现。 Shell扩展可能会将自己标记为不需要真正的COM,而在shell32内实现的事物将调用特殊的
处理文件系统的
当然,所有这些都是实现细节,并且您永远不要以为只要不初始化COM,所有这些都将起作用。
Because ShellExecute can delegate execution to Shell extensions (data
sources, context menu handlers, verb implementations) that are
activated using Component Object Model (COM), COM should be
initialized before ShellExecute is called. Some Shell extensions
require the COM single-threaded apartment (STA) type. In that case,
COM should be initialized as shown here:
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE) There are certainly instances where ShellExecute does not use one of
these types of Shell extension and those instances would not require
COM to be initialized at all. Nonetheless, it is good practice to
always initalize COM before using this function.
您可以使用以下帮助程序类在当前线程上自动初始化COM库。
1 2 3 4 5 6 7 8 9 10 | class COMRuntime { public: COMRuntime() { ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); } ~COMRuntime() { ::CoUninitialize(); } }; |
然后只需声明该类的一个实例:
1 2 3 4 5 6 | int main() { COMRuntime com; // the rest of your code } |