如何创建MAPI32.dll存根以实现从Word中“作为附件发送”?

1 投票
2 回答
3265 浏览
提问于 2025-04-15 14:30

微软的Word有一个“作为附件发送”的功能,这个功能可以在Outlook中创建一封新邮件,并把文档作为附件添加上去。

我想把Outlook换成我自己写的邮件程序,但我不知道该怎么做。目前我的邮件程序只是一个运行中的程序,接受一个文件名作为参数。

据我了解,“作为附件发送”这个功能是通过一个叫MAPI的东西实现的,可能是一些DLL或API。我需要修改我的程序,不仅仅是接受文件名的参数,还要能接收Word在“作为附件发送”时使用的MAPI调用。

另外,我还需要通过创建一个自己的MAPI32.dll小程序来更改默认的邮件程序,这个小程序只需将请求重定向到我的应用程序。

如果有人能提供更多关于如何实现这个功能的信息,我将非常感激!

2 个回答

0

好的,来回答我自己的问题。我需要创建一个包含“MAPISendDocuments”和/或“MAPISendMail”功能的DLL。

这个DLL可以取任何名字,并且在注册表中会被引用,路径是HKLM/Software/Clients/Mail/MyMailApp/DLLPath。

我找到了用Delphi编写的例子……

1

在自己写 MAPI 实现的时候,创建一个包含正确导出和调用约定的 DLL 是非常重要的,这样系统的 MAPI DLL(通常在 c:\windows\system32\mapi32.dll,应该和 mapistub.dll 一样)才能把调用传递给你的 DLL。MAPI 函数是用 __stdcall 这种调用方式来调用的。此外,设置正确的注册表键值也很关键,这样系统才能选择你的 MAPI DLL。看起来你已经找到了正确的注册表项,以便在你的应用程序进行 MAPI 调用时指定使用特定的 MAPI DLL。

我最近也做了同样的事情:写了自己的 MAPI DLL 框架,但在让系统调用我的扩展 MAPI 函数时遇到了很多麻烦。关键在于,mapi32.dll 会在 "foo@x" 这个入口点上调用 GetProcAddress,而不是在 MAPI 接口中的 "foo" 入口点上,以测试你的 DLL 是否符合扩展 MAPI 的要求(我觉得对于简单的 MAPI 调用,它不使用 "foo@x",而是直接使用 "foo" 这个入口点名称)。我还必须在我的项目中将框架库接口文件编译为 "C" 而不是 "C++",以确保所有符号名称都正确。

例如,MAPIInitialize 在你的源代码中应该这样声明:

HRESULT __stdcall MAPIInitialize( LPVOID lpMapiInit )
...

你还需要指定一个 .def 文件,里面包含这样的条目:

EXPORTS
    MAPIInitialize@4=_MAPIInitialize@4
    MAPIInitialize=_MAPIInitialize@4

对于简单的 MAPI 调用(与扩展 MAPI 调用相对),你可能不需要 "双重导出"。要查看一个正常工作的 MAPI 实现的导出内容,你可以这样做(如果你的系统上安装了 Outlook):

c:\> dumpbin /exports c:\Program Files\Common Files\SYSTEM\MSMAPI\1033\msmapi32.dll

(或者替换你在注册表中找到的路径,位于 HKLM\Software\Clients\Mail\Microsoft Outlook\DLLPathEx

撰写回答