Niko
Niko

Reputation: 1094

How to create .lnk File with Java?

I have found many parsing solutions for processing shortcuts for windows (.lnk), but I need to create them by my Java-Tool.

So my questions are:

Upvotes: 2

Views: 4917

Answers (2)

Josua Frank
Josua Frank

Reputation: 339

I can reccommend this repository on GitHub:

https://github.com/BlackOverlord666/mslinks

There I've found a simple solution to create shortcuts:

ShellLink.createLink("path/to/existing/file.txt", "path/to/the/future/shortcut.lnk");

If you want to read shortcuts:

File shortcut = ...;
String pathToExistingFile = new ShellLink(shortcut).resolveTarget();

Hope this helps you :)

Kind regards Josua Frank

Upvotes: 2

Ti Strga
Ti Strga

Reputation: 1390

We found that the most reliable way was to generate a temporary .js file and then spawn a WScript subprocess. It feels very kludgy, but it avoids any Java weaknesses and works with older JREs (this was important to us as Files.createSymbolicLink might not even be available for some of our use cases).

The result looked vaguely like the following. You could probably rewrite it to use Path instead of File and other NIO.2 features, etc. All the incoming variables are plain String instances, described at the bottom; they may be empty but are never null.

It's important to note that this code is for creating shortcuts inside a Windows "special folder", not just arbitrary locations. You can adapt it for that though.

File scriptFile = File.createTempFile ("whatever", ".js");

try (PrintWriter script = new PrintWriter(scriptFile)) {
    script.printf("try {\n");
    script.printf("wshshell = WScript.CreateObject(\"WScript.Shell\")\n");
    script.printf("specDir = wshshell.SpecialFolders(\"%s\")\n", folder);
    script.printf("shortcut = wshshell.CreateShortcut(specDir + \"\\\\%s.lnk\")\n", shortcutName);
    script.printf("shortcut.TargetPath = \"%s\"\n", target);
    script.printf("shortcut.Arguments = \"%s\"\n", arguments);
    script.printf("shortcut.WindowStyle = 1\n");
    script.printf("shortcut.HotKey = \"\"\n");
    if (icon.length() > 0)
        script.printf("shortcut.IconLocation = \"%s\"\n", icon);
    script.printf("shortcut.Description = \"%s\"\n", description);
    script.printf("shortcut.WorkingDirectory = \"%s\"\n", workingDir);
    script.printf("shortcut.Save()\n");
    script.printf("} catch (err) {\n");
    // Commented by default
    script.printf("/*WScript.Echo(\"name:\")\nWScript.Echo(err.name)\n");
    script.printf("WScript.Echo(\"message:\")\nWScript.Echo(err.message)\n");
    script.printf("WScript.Echo(\"description:\")\nWScript.Echo(err.description)\n");
    script.printf("WScript.Echo(\"stack:\")\nWScript.Echo(err.stack)\n");
    script.printf("*/\n");
    script.printf("WScript.Quit(1)\n");
    script.printf("}\n");
    script.close();

    // now run cscript.exe with arguments "//nologo" and the full
    // path to 'script', using something like ProcessBuilder and Process
}

You can test the exit value of the process, and if it's zero, delete the temp file. If something went wrong, you can leave the file behind for investigation, including editing the script by hand to uncomment the error dumping at the bottom.

The folder is the special Windows name for the destination folder, e.g., "SendTo" or "StartMenu", etc. The full list is on MSDN somewhere, but the main thing to remember is that they aren't necessarily the plain English names for those folders.

The shortcutName is, e.g., "My Program Shortcut". The target is what you think it is, and ought to be a full path for safest results.

The icon string is the funky Windows thing where you give an icon file name and index number, so something like "MyApp.ico, 0". The code above treats an empty icon string as using the system default.

The description becomes the shortcut's Properties -> Comment field. The arguments and workingDir can be left blank if you don't need to set them.

Upvotes: 1

Related Questions