4

我有三个程序 -

程序 1:另外使用 MAPI 的 Microsoft Outlook 插件。

程序 2:不使用 MAPI的独立 exe

程序3:使用 MAPI的独立 exe 。

这三个程序都是用 C# 编写的,并且在某些时候使用了 WinForms RichTextBox。

在使用 Office 365 程序“1”和“3”的 x64 Windows 8 安装上没有问题,但程序“2”在使用以下堆栈构造 RichTextBox 控件时立即崩溃:

System.IO.FileNotFoundException : C:\Program Files (x86)\Common Files\Microsoft Shared\Office15\riched20.dll
at System.Diagnostics.FileVersionInfo.GetVersionInfo(String fileName)
at System.Windows.Forms.RichTextBox.get_CreateParams()
at System.Windows.Forms.Control..ctor(Boolean autoInstallSyncContext)
at System.Windows.Forms.TextBoxBase..ctor()
at System.Windows.Forms.RichTextBox..ctor()
<snip>

反汇编 RichTextBox.get_CreateParams() 显示它在“riched20.dll”上调用 LoadLibrary,然后在加载的模块上调用 GetModuleFileName。

对于程序 2,Visual Studio 告诉我它已从路径“C:\Program Files\Microsoft Office 15\root\vfs\ProgramFilesCommonX86\Microsoft Shared\OFFICE15\RICHED20.DLL”加载了riched20.dll。

对 FileVersionInfo.GetVersionInfo() 的调用随后会失败,因为给出的路径不存在。

但是 - 程序 1(outlook 插件)也从同一路径加载了riched20.dll - 但不知何故成功了!

不加载 MAPI 的程序 2 工作正常,它从 C:\Windows\syswow62 加载riched20.dll

程序 3 在创建富文本框之前初始化 MAPI,并且我知道某些 MAPI 函数会将您当前的工作目录更改为 MAPI 目录。这大概解释了为什么程序 3 加载 office 的 riched20.dll 而程序 2 加载 system32 副本。

我怀疑程序 1 工作和程序 3 失败之间的区别在于路径中的 vfs 代表“虚拟文件系统”,因此作为 Outlook 插件运行的程序 1 可以使用不存在的路径以某种方式找到riched20.dll真的存在。

这三个程序都适用于以前版本的 office。

作为一种解决方法,在初始化 MAPI 之前自己调用 'LoadLibrary("riched20.dll") 会使问题消失 - 但感觉就像一个可怕的黑客攻击。

我也找不到有关此“vfs”文件路径及其在 Internet 上的含义的任何信息。

对于我自己的教育,有没有人能够更好地解释这里发生了什么?

更新:据我所知,这与“点击运行”功能有关。

4

1 回答 1

6

解决方案是在初始化 MAPI 之前使用 pinvoke 在“riched20.dll”上调用 LoadLibrary。

[DllImport("kernel32", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern IntPtr LoadLibrary(string lpFileName);

LoadLibrary("riched20");
于 2013-07-26T06:00:12.353 回答