Reputation: 1094
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
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
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