Search code examples
command-lineinstall4j

How to pass a path from "open with" to an executable created by install4j?


I'm trying to enable an executable (created by install4j) to work with a path given by an "open with" user interaction on a file.

On macOS (same should be true for other platforms AFAIK), when one right-clicks a file and chooses "open with -> Application", the application will be fired up and the path to the file will be given as an argument.

I read a lot of install4j tutorials, found a lot of command-line-related stuff, but didn't find how to get this running.

Currently, when I open a file with the created App, the path will be ignored. When I start my Java application via command line, it works fine.

Any ideas what to set up in install4j to make this work?

Thanks a lot.

Edit: After Ingo's suggestion I added this to my launcher class, but somehow it doesn't get called:

        public void start(Stage aPrimaryStage) {

            StartupNotification.registerStartupListener(aPath -> {

                logger.log("StartupListenerCalled: " + LocalDateTime.now());

                try {

                    setFilesListToStageProperties(externalPathStringToFilesList(aPath), aPrimaryStage.getProperties());
                }
                catch (IOException e) {

                    showError(Thread.currentThread(), e);
                }
            });

            logger.log("Application start: " + LocalDateTime.now());

            super.start(aPrimaryStage);
        }

Solution

  • On macOS (same should be true for other platforms AFAIK), when one right- clicks a file and chooses "open with -> Application", the application will be fired up and the path to the file will be given as an argument.

    This is not the case for application bundles on macOS. You have to use the startup notification API. This also works for single instance mode on Windows and Linux, where only the first invocation will pass the file path as an argument to the main method.

    The startup listener API uses java.awt.Desktop.setOpenFileHandler under the hood which only works if you register a file association. From the documentation on that method:

    Please note that for Mac OS, notifications are only sent if the Java app is a bundled application, with a CFBundleDocumentTypes array present in its Info.plist.

    For a method to add a file association for all file types, see this blog post:

    https://www.cocoanetics.com/2013/01/open-in-all-files/

    In the launcher wizard, under Executable info-> macOS options, you can add an arbitrary fragment to the Info.plist file.