1

I have created a Java application where a user can drag and drop a file to save it into a specified folder. I am using FileDrop and unfortunately it doesn't work with emails dragged and dropped directly from Outlook. It works when the email is dropped to the desktop first (a .eml file is created) and then dropped into the application, but I really want to bypass this step.
You can see my code below:

new FileDrop(panel, new FileDrop.Listener() {
    public void filesDropped(java.io.File[] files) {
        for (int i=0; i<files.length; i++) {
            File newFile = files[i];
            byte[] myByteArray = null;
            try { //get the data of the file into a byte array
                myByteArray = org.apache.commons.io.FileUtils.readFileToByteArray(newFile);
            } catch (IOException e1) {
                e1.printStackTrace();
            }

            String newFileName = newFile.getName();

            try { //create the file
                FileOutputStream file = new FileOutputStream("projects/"+ newFileName);
                file.write(myByteArray);
                file.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
});

I would love to hear any possible solutions to this problem.
By the way, this is part of the error message I am getting, pointing out that the problem occurs in the public void filesDropped(java.io.File[] files) { line, since the email that was dropped into the application is not recognized as a file yet (I guess).

...
2015-06-04 12:10:50.860 java[718:71442] Couldn't get a copy of an HFS Promise from the pasteboard
2015-06-04 12:10:50.860 java[718:71442] Looked for HFSPromises on the pasteboard, but found none.
Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: URI is not hierarchical
    at java.io.File.<init>(File.java:363)
    at net.iharder.dnd.FileDrop.createFileArray(FileDrop.java:453)
    ...

Thanks in advance.

laertis
  • 13
  • 6
  • 2
    Something dragged from an application isn't a "file" (always), it's some sort of other data and you need to ascertain the data flavor(s) that the application uses to export the object and "extract" the data via the appropriate means as per the data flavor(s) – MadProgrammer Jun 04 '15 at 10:11
  • @MadProgrammer Thanks for the quick response! Is there a way to use FileDrop for my problem? Or would you propose a solution similar to this: http://stackoverflow.com/questions/1204580/swing-application-drag-drop-to-the-desktop-folder – laertis Jun 04 '15 at 11:05
  • Without knowing more about the data flavors the outlook supports, then I'd say know, you can't use FileDrop, and you're going to have to either use the core D'n'D api or the transferable api – MadProgrammer Jun 04 '15 at 11:29
  • From what I experienced with Outlook, Swing and Drag-and-Drop, Outlook only transfers some data of the dragged email (subject, recipient, ...). No data about the actual content or attachments is transfered. So what you need to do is, get notified by your code that a drop event has happend from Outlook and then use some COM-Framework to access Outlook via COM. Then you can get the needed data yourself... Btw, Thunderbird worked perfect with my code without any changes. I have never implemented this COM-communication, but look here: [link](https://community.oracle.com/thread/1160935?tstart=0) – schokosocke Jul 22 '16 at 13:08

1 Answers1

0

Outlook does provide a FileDescriptor with the following information:

  • Number of Items dropped
  • For each Item: Filename (e.g. Test.msg + IDataObject) which points to an IStorage
  • There is one IStorage per dragged item
  • The IStorage will be a virtual file system according to MS specification of Compound Files (used in MS Office - e. g. .xls, .doc, but also .msg).
  • The IStorage is then similar to File/Folder structure where Folders are represented by IStorage objects and Files by IStreams
  • In the IStream one would find the actual contents of the E-Mail, like:
    • Subject
    • Recipient
    • E-Mail body
    • Attachments

I also struggled quite a time with the assumption Outlook passes the binary file over the dragndrop interface. Due to interoperability with other Office programs, Outlook passes the Compound File structure instead. So one needs to puzzle those things together. If one saves the received elements from Outlook to a file, this would not be a 1:1 as if you exported from Outlook to disk (binary identical), but a file with the same content.

For the complete solution the approach works as follows:

  • Get File Descriptor
  • For each File get
    • Filename
    • Pointer to IDataObject
    • Get Root IStorage from IDataObject
      • Iterate sub elements of IStorage
        • If sub element is an IStream, process IStream
        • If sub element is an IStorage, recursively walk back to 'Iterate sub elements'

What makes it complicated is the interface to Win32 OLE which is using pointers. Furthermore the interface return types are not that easy to interpret if you are going into errors.

For more details, please find my answer in this post: Can I drag items from Outlook into my SWT application?

I have created a small library providing an SWT Transfer type for Outlook items. You could find it on GitHub: https://github.com/HendrikHoetker/OutlookItemTransfer

Hope this helps, in case you have more questions, please drop a comment below.