CoCreateInstance CLSID_IConverterSession 在 Office 2016 中失败

CoCreateInstance CLSID_IConverterSession fails with Office 2016

我正在使用 IConverterSession 从 mhtm 文件创建邮件项目。这适用于小于 2016 的 Outlook 版本。对于 Office 2016,无法创建 IConverterSession。

如果您使用的是 运行ning C2R(点击运行)版本的 Outlook 2016,所有注册表项都已虚拟化 - 请参阅下面的注册表项(%s 需要替换为Outlook 版本,例如 16.0)。由于 COM 系统不在那里查找,您将需要实现您自己的 CoCreateInstance 版本,该版本从键中读取默认值以找出 dll 文件名,然后调用 LoadLibrary / GetProcAddress("DllGetClassObject") / DllGetClassObject(..., IID_IClassFactory, ...) / IClassFactory.CreateInstance.

SOFTWARE\Microsoft\Office\%s.0\ClickToRun\REGISTRY\MACHINE\Software\Classes\CLSID\%s\InprocServer32
SOFTWARE\Microsoft\Office\%s.0\ClickToRun\REGISTRY\MACHINE\Software\Classes\Wow6432Node\CLSID\%s\InprocServer32
SOFTWARE\Microsoft\Office\ClickToRun\REGISTRY\MACHINE\Software\Classes\CLSID\%s\InprocServer32
SOFTWARE\Microsoft\Office\ClickToRun\REGISTRY\MACHINE\Software\Classes\Wow6432Node\CLSID\%s\InprocServer32

您不必自己实施 CoCreateInstance(),而必须启用注册表重定向以启用 Outlook 的 C2R(点击-运行)虚拟化,它使用迂回的方式将调用重定向到 RegOpenKey() .启用该重定向后,只需使用普通的 CoCreateInstance()。

你自己实现 CoCreateInstance() 不起作用的原因是,转换器也会在内部调用 CoCreateInstance() 并且会像你原来的调用一样失败,因为它在正常情况下找不到 CLSID注册表的配置单元。

我自己通过查看 jitv.dll 导出找到了代码。参数可能有误,但作为第一次启动它没有崩溃。要找出参数,我必须调试 Office 应用程序并查看反汇编(或任何志愿者?)。

这里是对我有用的实验代码:

HMODULE jitv = ::LoadLibrary(TEXT("jitv.dll"));
if (jitv) {
FARPROC efv  = ::GetProcAddress(jitv, "EnableFullVirtualization");
if(efv)
  efv();
  // call CoCreateInstance(guid::CLSID_IConverterSession)
  // and do your work
}

if (jitv)
  FreeLibrary(jitv);

jitv.dll 中还有一些其他导出项,其名称大多不言自明:

  • "APIExportForDetours"
  • "DisableVirtualizationOnThread"
  • "EnableVirtualizationOnThread"
  • "IsCurrentThreadVirtualized"

感谢 nickekallen 的 this posting,他提到了那个 dll 并让我想到了那个想法。