COM Interop&展望 - 让Outlook可见?

时间:2010-05-26 16:07:46

标签: com interop outlook visible

我正在从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显示其主窗口?奖励积分,如果我可以让它禁止用户关闭实例,但我会满足于只显示窗口:)

3 个答案:

答案 0 :(得分:3)

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

mailItem.Display();

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

答案 1 :(得分:2)

我正常测试以查看“Outlook”进程是否首先运行,如果没有,则将shell升级到Outlook然后附加。这样你永远不会得到一个隐藏的过程。

实际上没有办法取消关闭的Outlook,你可以挂钩应用程序退出事件来断开连接并在你的应用程序中进行处理。

答案 2 :(得分:0)

我刚才遇到了这个问题,因为我遇到了同样的挑战。我对接受的答案并不完全满意,因为这意味着我必须确定Outlook.exe的完整路径。 “加壳Outlook.exe”无效。因此,我寻找并找到了另一种解决方案。但是,在我提出这一点之前,让我们先看看如何确定Outlook.exe的完整路径。

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

获取Path值。
  • HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\16.0\Outlook\InstallRoot

注册码(假设您拥有Office 16,也称为Office 2016或2019),并构建Outlook.exe的完整路径。在我的计算机上,Path的值是

  • C:\Program Files\Microsoft Office\root\Office16

因此完整路径为

  • C:\Program Files\Microsoft Office\root\Office16\Outlook.exe

但是,您需要考虑到用户可能安装了较旧的版本(例如,Office 15,又名Office 2013)或更新的Office版本,并选择了适当的注册表项。您还可以通过获取

的默认值来获得Office版本
  • HKEY_CLASSES_ROOT\Outlook.Application\CurVer

键(例如Outlook.Application.16)。据此,您可以推断版本号(例如16)并构建您的注册表项的段(例如16.0)。或者,您可以尝试使用具有Outlook\InstallRoot值的子项Path查找密钥。无论如何,您可能会明白为什么我要避免这种情况。

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

using Outlook = Microsoft.Office.Interop.Outlook;

要使Outlook在当前看不到窗口的情况下显示其主窗口,我编写了以下实用程序方法:

private static void EnsureOutlookIsVisible(Outlook.Application outlook)
{
    object window = null;
    NameSpace ns = null;
    MAPIFolder folder = null;

    try
    {
        // Check whether Outlook has an active window. If so, Outlook is visible
        // and we don't have to do anything.
        window = outlook.ActiveWindow();
        if (window != null) return;

        // No active window is shown, so Outlook is not visible and we need to
        // have Outlook display a window.
        ns = outlook.GetNamespace("MAPI");
        folder = ns.GetDefaultFolder(OlDefaultFolders.olFolderInbox);
        folder.Display();
    }
    finally
    {
        folder.ReleaseComObject();
        ns.ReleaseComObject();
        window.ReleaseComObject();
    }
}

上述方法使用以下扩展方法来释放COM对象:

public static void ReleaseComObject<T>(this T resource) where T : class
{
    if (resource != null && Marshal.IsComObject(resource))
    {
        Marshal.ReleaseComObject(resource);
    }
}

使用上述方法,要附加到新的或现有的Outlook进程并确保Outlook显示其主窗口,只需执行以下两行代码:

var outlook = new Outlook.Application();
EnsureOutlookIsVisible(outlook);