CoCreateInstance CLSID_IConverterSession因Office 2016而失败

时间:2017-10-04 05:51:03

标签: outlook-addin

我使用IConverterSession从mhtm文件创建邮件项目。这适用于Outlook版本< 2016.使用Office 2016,无法创建IConverterSession。

2 个答案:

答案 0 :(得分:0)

如果您运行的是Outlook 2016的C2R(点击运行)版本,则所有注册表项都已虚拟化 - 请参阅下面的注册表项(%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

答案 1 :(得分:0)

您不必启用自己的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,并将我带入了这个想法。