如何在Outlook中创建电子邮件并使其对用户可见

时间:2013-08-05 12:06:03

标签: java email outlook ole

我想使用Outlook和OLE客户端创建一个带有Java应用程序的电子邮件。

我搜索了一些例子,发现了不少。他们都以同样的方式开始:

创建显示,外壳,OLE框架和OLE客户端站点。

但是我在这几个步骤中遇到错误:

Display display = new Display();
Shell shell = new Shell(display);

shell.setText("Outlook Automation");
shell.setLayout(new FillLayout());

OleFrame frm = new OleFrame(shell, SWT.NONE);

OleClientSite site = new OleClientSite(frm, SWT.NONE,
                "Outlook.Application");

我收到以下错误:

Exception in thread "main" org.eclipse.swt.SWTException: Failed to create Ole Client. result = -2147221164
at org.eclipse.swt.ole.win32.OLE.error(OLE.java:302)
at org.eclipse.swt.ole.win32.OleClientSite.<init>(OleClientSite.java:242)
at outlooktest.Main.main(Main.java:27)

我不知道OLE,我不确定我做错了什么。我缺少一些依赖吗?有人知道这个错误是什么吗?我用Google搜索了错误代码,但没有找到任何内容。

修改

如果没有人知道为什么OLE不适合我,我还有另外一个问题。是否有可能,或者是否有图书馆,可以创建一个Outlook电子邮件并进行设置(主题,正文等)但不发送它但是让用户可以看到更改内容?

编辑2

x86和x64 jar文件无效,同样的错误。我还得到了最新版本的SWT for x86和x64。操作系统也是x64和java,所以我不能使用x86 SWT库。使用x64时会出现上述错误。 Outlook版本为15(Outlook 2013)。

希望这有帮助吗?

我通过Processbuilder创建了电子邮件,但只能使用mailto:参数。这里的问题是:

  • 我想跟踪进程的状态。我想知道电子​​邮件什么时候关闭/发送。
  • 我想将一张图片(BufferedImage)从剪贴板中插入到Body中,这对于mailto参数来说根本不可能。

4 个答案:

答案 0 :(得分:3)

对我而言,根据tutorial on vogella.com,这很有效。我还尝试了您的最小代码示例,并在创建OLE客户端期间没有出错。顺便说一下,我使用了SWT 4.3。

有点偏离主题,但它必须是Outlook吗?我的意思是,您是否只想自动发送电子邮件 - 您可以使用JavaMail并无头地执行此操作,即无需自动化实际的GUI客户端。我希望使用Outlook或其他电子邮件客户端的唯一原因是:

  • 您需要在发件箱中发送已发送的消息以供参考。
  • Outlook连接到Exchange服务器,该服务器配置为不接受JavaMail使用的SMTP连接。
  • 您可能希望撰写基本信息并将其显示给用户,以便她可以在发送之前以交互方式添加附件或编辑文本。

但如果它只是关于自动发送电子邮件,正如我所说,我会推荐JavaMail。


更新:我从home page下载了SWT,在我的情况下是最新稳定的release 4.3 for Windows。在ZIP存档中,您需要的文件是 swt.jar

我的示例代码看起来像这样,工作正常:

package de.scrum_master.ole;

import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.ole.win32.OLE;
import org.eclipse.swt.ole.win32.OleAutomation;
import org.eclipse.swt.ole.win32.OleClientSite;
import org.eclipse.swt.ole.win32.OleFrame;
import org.eclipse.swt.ole.win32.Variant;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

public class OutlookMail {
    public static void main(String[] args) {
        sendEMail();
    }

    public static void sendEMail() {
        Display display = new Display();
        Shell shell = new Shell(display);
        OleFrame frame = new OleFrame(shell, SWT.NONE);

        // This should start outlook if it is not running yet
//      OleClientSite site = new OleClientSite(frame, SWT.NONE, "OVCtl.OVCtl");
//      site.doVerb(OLE.OLEIVERB_INPLACEACTIVATE);

        // Now get the outlook application
        OleClientSite site2 = new OleClientSite(frame, SWT.NONE, "Outlook.Application");
        OleAutomation outlook = new OleAutomation(site2);

        OleAutomation mail = invoke(outlook, "CreateItem", 0 /* Mail item */).getAutomation();

        setProperty(mail, "BodyFormat", 2 /* HTML */);
        setProperty(mail, "Subject", "My test subject");
//      setProperty(mail, "From", "my@sender.org");
        setProperty(mail, "To", "<John Doe> my@recipient.org");
        setProperty(mail, "HtmlBody", "<html><body>This is an <b>HTML</b> test body.</body></html>");

//      if (null != attachmentPaths) {
//          for (String attachmentPath : attachmentPaths) {
//              File file = new File(attachmentPath);
//              if (file.exists()) {
//                  OleAutomation attachments = getProperty(mail, "Attachments");
//                  invoke(attachments, "Add", attachmentPath);
//              }
//          }
//      }

        invoke(mail, "Display" /* or "Send" */);

    }

    private static OleAutomation getProperty(OleAutomation auto, String name) {
        Variant varResult = auto.getProperty(property(auto, name));
        if (varResult != null && varResult.getType() != OLE.VT_EMPTY) {
            OleAutomation result = varResult.getAutomation();
            varResult.dispose();
            return result;
        }
        return null;
    }

    private static Variant invoke(OleAutomation auto, String command,
            String value) {
        return auto.invoke(property(auto, command),
                new Variant[] { new Variant(value) });
    }

    private static Variant invoke(OleAutomation auto, String command) {
        return auto.invoke(property(auto, command));
    }

    private static Variant invoke(OleAutomation auto, String command, int value) {
        return auto.invoke(property(auto, command),
                new Variant[] { new Variant(value) });
    }

    private static boolean setProperty(OleAutomation auto, String name,
            String value) {
        return auto.setProperty(property(auto, name), new Variant(value));
    }

    private static boolean setProperty(OleAutomation auto, String name,
            int value) {
        return auto.setProperty(property(auto, name), new Variant(value));
    }

    private static int property(OleAutomation auto, String name) {
        return auto.getIDsOfNames(new String[] { name })[0];
    }
}

我在末尾注释了附件部分以及第一个OLE命令,因为对我来说它也可以在没有它的情况下工作。它虽然使用它没有任何损害,也许你需要它。试试吧。

我注释掉标题“From”行的原因是它没有效果。要更改发件人,您可能需要另一个代码段来切换Outlook配置文件或在配置文件中切换多个预配置的发件人。默认情况下,它只会使用您的默认配置文件。

告诉我它是否有帮助。

答案 1 :(得分:0)

玉米,

System.Diagnostics.Process.Start("mailto:someone@example.com?Subject=Hello%20again&body=your%20textBody%20here")

使用上面的代码用预定义的mailto,邮件的主题和正文打开Outlook邮件,请你解释一下我们如何在CC中添加地址。

答案 2 :(得分:0)

您的MS Outlook可能是32位(x86)。因此64位(x64)SWT无法启动Outlook。您需要使用不能在64位JVM上运行的32位SWT Jar文件。所以你需要安装32位JVM(JRE)。

即使您运行的是64位Windows,您仍然可以下载并安装32位(x86)JRE并运行您的应用程序。

答案 3 :(得分:-1)

如果您使用网络内容,这可以帮助您:

<!DOCTYPE html>
<html>
<body>

<p>
This is an email link:
<a href="mailto:someone@example.com?Subject=Hello%20again&body=your%20textBody%20here" target="_top">
Send Mail</a>
</p>

<p>
<b>Note:</b> Spaces between words should be replaced by %20 to ensure that the browser will display the text properly.
</p>

</body>
</html>

但在应用程序中,您可以启动进程mailto:

喜欢

System.Diagnostics.Process.Start("mailto:someone@example.com?Subject=Hello%20again&body=your%20textBody%20here")

它适用于所有电子邮件客户端