2

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:

  • How can they be created?
  • (or is it better to use Files.createSymbolicLink?) - The problem is that they have Filesize zero and are not treated like "normal" files (so when I want to delete empty folders, symbolic shortcuts (inside) are also deleted because they are not recognized as "normal" file))
Niko
  • 1,054
  • 5
  • 25
  • 52
  • There is a nice Java-only API mentioned [here](http://stackoverflow.com/questions/19629034). No scripting involved. The API is quite impressive on first look. – ADTC Jun 19 '14 at 23:05

2 Answers2

2

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

Josua Frank
  • 331
  • 3
  • 6
  • This seems good because the .lnk file is just a bunch of bytes so why not write them out. – Yetti99 Aug 23 '20 at 21:14
  • doesn't seem to be a good solution. only works on windows, requires you to download a unkown untrusted user running hard coded exe files – nullsector76 Dec 25 '20 at 05:35
1

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.

Ti Strga
  • 1,353
  • 18
  • 40