4

私は3つのプログラムを持っています -

プログラム 1: MAPI を追加で使用する Microsoft Outlook アドイン。

プログラム 2: MAPI を使用しないスタンドアロン exe

プログラム 3: MAPIを使用するスタンドアロン exe 。

3 つのプログラムはすべて C# で記述されており、ある時点で WinForms RichTextBox を使用します。

Office 365 を使用した x64 Windows 8 インストールでは、プログラム '1' と '3' には問題がありませんが、プログラム '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-addin) も同じパスから 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 を何らかの方法で見つけることができるためだと思います。本当に存在します。

3 つのプログラムはすべて、以前のバージョンの Office で動作します。

回避策として、MAPI を初期化する前に LoadLibrary("riched20.dll") を自分で呼び出すと、問題は解決しますが、ひどいハックのように感じます。

また、この「vfs」ファイル パスとその意味に関する情報をインターネット上で見つけることもできませんでした。

私自身の教育のために、ここで何が起こっているのかをよりよく説明できる人はいますか?

更新:「クリックして実行」機能と関係があることを突き止めました。

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 に答える