COM互操作&;Outlook-使Outlook可见?

COM互操作&;Outlook-使Outlook可见?,com,interop,outlook,visible,Com,Interop,Outlook,Visible,我正在从一个VB.NET程序中自动化Outlook,根据用户的请求将项目传输到日历和联系人中。这一切都在起作用,这不是问题所在;问题是,在Outlook尚未打开时自动执行这样的操作会创建一个隐藏实例。我也许能理解这是多么有用,可以阻止用户在您仍在操作时关闭它,但由于Outlook似乎只强制执行一个实例,如果用户试图检查在我的程序仍挂接到Outlook时所做的更改,什么都没有发生-一个实例就是隐藏的实例,用户看不到任何东西 在COM自动化的旧时代,我曾经能够使Word或Excel可见,但我似乎无法

我正在从一个VB.NET程序中自动化Outlook,根据用户的请求将项目传输到日历和联系人中。这一切都在起作用,这不是问题所在;问题是,在Outlook尚未打开时自动执行这样的操作会创建一个隐藏实例。我也许能理解这是多么有用,可以阻止用户在您仍在操作时关闭它,但由于Outlook似乎只强制执行一个实例,如果用户试图检查在我的程序仍挂接到Outlook时所做的更改,什么都没有发生-一个实例就是隐藏的实例,用户看不到任何东西

在COM自动化的旧时代,我曾经能够使Word或Excel可见,但我似乎无法用Outlook做到这一点。我试过:

OutlookApp.Visible = True

OutlookApp.Application.Visible = True

OutlookApp.ActiveWindow.Visible = True

OutlookApp.ActiveExplorer.Display() 
但它们都不起作用


这并不重要,但有人知道我是否可以让Outlook显示其主窗口吗?如果我可以让它禁止用户关闭实例,但我可以满足于只显示窗口:)

我通常会先测试“Outlook”进程是否正在运行,如果没有,则打开Outlook.exe,然后附加。这样你就永远不会得到一个隐藏的过程


确实没有办法取消关闭outlook,但您可以挂起应用程序退出事件以断开连接并在应用程序中进行处理。

您可以这样显示您的创建邮件:

mailItem.Display();

这是c#代码,但我认为,这可能与你的vb很接近。

我刚才遇到这个问题,因为我遇到了同样的挑战。我对接受的答案并不完全满意,因为这意味着我必须确定
Outlook.exe
的完整路径。“向上剥离Outlook.exe”不起作用。因此,我寻找并找到了另一个解决方案。但在我介绍之前,让我们先看看如果您想确定
Outlook.exe的完整路径,您可以如何确定该路径

要确定
Outlook.exe的完整路径
,需要从

  • HKEY\u LOCAL\u MACHINE\SOFTWARE\Microsoft\Office\16.0\Outlook\InstallRoot
注册表项(假设您有Office 16,也称Office 2016或2019)并生成
Outlook.exe
的完整路径。在我的机器上,
路径
值为

  • C:\ProgramFiles\Microsoft Office\root\Office16
因此,完整的路径是

  • C:\ProgramFiles\Microsoft Office\root\Office16\Outlook.exe
但是,您需要考虑到用户可能安装了较旧的Office版本(例如,Office 15,又称Office 2013)或较新的Office版本,并选择适当的注册表项。您还可以通过检索

  • HKEY\u CLASSES\u ROOT\Outlook.Application\CurVer
键(例如,
Outlook.Application.16
)。由此,您可以推断版本号(例如,
16
)并构建注册表项的段(例如,
16.0
)。或者,您可以尝试查找子键
Outlook\InstallRoot
具有
Path
值的键。不管怎样,你可能知道我为什么要避免这样

因此,让我们看一个更简单的解决方案,注意我正在使用多个Office应用程序,因此,有以下使用说明:

using Outlook = Microsoft.Office.Interop.Outlook;
为了使Outlook在当前没有可见窗口时显示其主窗口,我编写了以下实用程序方法:

private static void确保outlookisvisible(Outlook.Application Outlook)
{
对象窗口=空;
名称空间ns=null;
mapifolderfolder=null;
尝试
{
//检查Outlook是否有活动窗口。如果有,则Outlook可见
//我们什么都不用做。
window=outlook.ActiveWindow();
如果(窗口!=null)返回;
//没有显示活动窗口,因此Outlook不可见,我们需要
//让Outlook显示一个窗口。
ns=outlook.GetNamespace(“MAPI”);
folder=ns.GetDefaultFolder(OlDefaultFolders.olFolderInbox);
folder.Display();
}
最后
{
folder.ReleaseComObject();
ns.ReleaseComObject();
window.ReleaseComObject();
}
}
上述方法使用以下扩展方法来释放COM对象:

公共静态void ReleaseComObject(此T资源),其中T:class
{
if(资源!=null&&Marshal.IsComObject(资源))
{
Marshal.ReleaseComObject(资源);
}
}
使用上述方法,要附加到新的或现有的Outlook进程并确保Outlook显示其主窗口,只需以下两行代码:

var outlook=new outlook.Application();
确保OutlookisVisible(outlook);

Hmmm,我想说“我理解,但这取决于了解Outlook的路径和文件名…”。现在我终于明白了,我们确实知道——注册中心将告诉我们谁提供“Outlook.Application”。所以,谢谢-很高兴我现在回到这个答案上来。如果你现在读这个,看看我下面的答案,如果你使用.NET,它提供了一个更简单的解决方案。仅仅9年零9个月后,我遇到了同样的问题,找到了一个我在下面的答案中描述的简单解决方案。不需要查看注册表。。。