我正在尝试将从旧电脑(64 位 Windows 7 Ultimate、零售 Office x86)上运行的 Outlook.exe 读取 MailItems 的 x86 应用程序迁移到较新的电脑(64 位 Windows 10 Pro、Office 365 x86)。我在两台电脑上都使用VS2010。我有“嵌入互操作类型”= TRUE。
从 Outlook 获取应用程序和命名空间时,应用程序失败(请参阅下面的代码和异常)。我有理由相信我没有引用正确的 Outlook .dll 或 PIA。我在网上搜索了可能适用于我的配置的当前信息。我发现的最好的是无法添加对 Outlook 2016 (Office 365) Interop (16.0.0.0) 的引用
该问题的解决方案提出了两个修复方案。 “强制应用程序为 x86 或将 Office 365 安装为 64 位”
原因是 Visual Studio 仅将 64 位版本的 .dll 注册到 64 位 Windows 上的 GAC。
就我而言,该应用程序始终是 x86,而 Office 365 是而且必须是 x86。我使用 MS Access 和 Excel VBA 模块,两者都按预期工作,其引用的 .dll 没有问题。
我的问题:我应该引用哪些.dll?在哪里可以找到它们,或者我需要 DirectCast 一些东西吗?
详情:
下面的代码是问题代码的摘录。只有“尝试”之前和之后的两行对于这个问题来说是实际问题。
导入 Microsoft.Office.Interop.Outlook '涉及 GUI 和数据结构设置的代码和声明 ... '从 Form.Shown 处理程序调用 私有子 GetMessages() 调暗应用程序作为 Microsoft.Office.Interop.Outlook.Application = Nothing Dim ns As Microsoft.Office.Interop.Outlook.NameSpace = Nothing 尝试 app = New Application() '执行...但是 ns = app.GetNamespace("MAPI") '抛出异常 ns.Logon(什么都没有,什么都没有,假,假) '...读取邮件项目的代码... 捕获 ex 作为 System.Runtime.InteropServices.COMException Debug.WriteLine(例如.ToString()) 最后 ns = 无 子文件夹 = 无 收件箱文件夹=无 'app.Quit() '可能不需要 应用=什么都没有 结束尝试 结束子
运行时,上面的代码在 GetNamespace 调用时抛出以下异常。
无法将类型“Microsoft.Office.Interop.Outlook.ApplicationClass”的 COM 对象强制转换为接口类型“Microsoft.Office.Interop.Outlook._Application”。此操作失败,因为对 IID 为“{00063001-0000-0000-C000-000000000046}”的接口的 COM 组件上的 QueryInterface 调用由于以下错误而失败:找不到元素。 (HRESULT 异常:0x8002802B (TYPE_E_ELEMENTNOTFOUND))。
当然,我的代码取决于是否有正确的引用。我通过将解决方案从旧电脑复制到新电脑来实现这一点。然后我将它加载到VS2010中并重建它。此重建将参考更改为:
Microsoft.Office.Core——C:\WINDOWS ssembly\GAC_MSIL\Office
.0.0.0__71e9bce111e9429c\Office.dll
Microsoft.Office.InterOp.Outlook - C:\WINDOWS ssembly\GAC_MSIL\Microsoft.Office.Interop.Outlook
.0.0.0__71e9bce111e9429c\Microsoft.Office.Interop.Outlook.dll
尝试“修复”您的 Microsoft Office 安装。转到程序和功能,选择修改,然后选择在线修复。看来你的 Windows 注册表项被搞乱了。了解有关此类问题的更多信息:
我在使用在桌面上构建的代码时遇到了类似的问题,但由于该问题而无法运行。我使用这种方法来获取主类中的应用程序的属性。这似乎有效: 首先,我使用别名来使内容更易于阅读,因此 XL 是使用 using 语句设置的:
using XL=Microsoft.Office.Interop.Excel;
然后我使用对应用程序的显式转换,而不是仅使用我使用的“应用程序”(XL.Application
public XL.Application XlApp
{
get
{
if (xlApp == null)
{
xlApp = new XL.Application();
}
xlApp.DisplayAlerts = false;
return xlApp;
}
set => xlApp = (XL.Application)value;
}
我希望这会带来一些好处,即使它不能完全解决问题。
乔伊