我有一个 32 位旧版 VB6 应用程序,它使用 COM 组件自动化 Outlook 发送电子邮件。要求是电子邮件需要出现在 Outlook 的“已发送邮件”文件夹中。更糟糕的是,不允许应用程序弹出通常的安全、警告或确认消息。
在 64 位 Office 出现之前,此应用程序可以正常运行。32 位进程无法自动执行 64 位 Outlook。
我想出的想法如下:
使用在 CCW 中运行的 .NET WCF 客户端替换 COM 组件(.NET 伪装成 COM)
此 COM 组件使用 netTcpBinding 调用作为 64 位进程运行的 WCF 服务。
WCF 服务(作为本地系统运行)然后以用户身份启动 64 位控制台应用程序,并使用扩展 MAPI 库发送电子邮件。
第三步的原因有两个:
如果您告诉 MAPI 发送电子邮件,MAPI 会要求确认。扩展 MAPI 没有。这意味着我们必须使用来自 Microsoft 的正确 64 位头文件编译一个 C++ 扩展 MAPI 库,并从我们的 .NET 代码中“调用”它。
在 WCF 中模拟(松散使用的术语)用户会导致注册表配置单元加载不正确。换句话说,当扩展 MAPI 尝试从 HKCU 加载配置文件时,它会失败。这意味着我们必须启动一个新进程来基本上“RunAs”正确的用户。
这一切实际上都在实践中有效,但我需要对以下内容进行一些解释:
如果我使用命令行参数中所需的所有信息运行控制台应用程序,MAPI 将无法登录。但是,如果我用 1 个表单编译这个与 Windows 应用程序相同的代码,并且在表单的 OnLoad() 方法中使用完全相同的代码,那么它会成功。谁能解释为什么?
要以当前登录用户(不是本地系统)的身份从 WCF 服务运行“WinForms”应用程序,我执行以下操作以获取正确的令牌:
sessionID = (int)WTSGetActiveConsoleSessionId();
ret = WTSQueryUserToken(sessionID, out currentToken);
有没有办法解决?当然,使用 WCF 的内置模拟会更好。