如何在Java中提取.lnk文件的目标路径、命令行参数及工作目录?
Great question! I’ve faced this exact limitation with the WindowsShortcut library you referenced—its default implementation only grabs the base target path, not the extra metadata like arguments or working directory. Here are two reliable ways to solve this:
Option 1: Extend the Existing WindowsShortcut Library
Since the library is open-source, you can modify it to parse the additional fields defined in the Windows .lnk file format. Here’s how:
Add Member Variables
First, update theWindowsShortcutclass to store the new data:private String commandLineArguments; private String workingDirectory;Modify the Constructor to Parse New Fields
The .lnk format stores the working directory in the Link Info section and command-line arguments in the String Data section. You’ll need to add parsing logic in the constructor after the existing code that extractsrealFilename. For example:// Inside the WindowsShortcut(File file) constructor // ... existing parsing code ... // Parse working directory (from Link Info section) int workingDirOffset = ...; // Calculate using the format's offset rules int workingDirLength = ...; // Get length from the format's structure this.workingDirectory = readUnicodeString(file, workingDirOffset, workingDirLength); // Parse command-line arguments (from String Data section) int argsOffset = ...; // Calculate using the format's offset rules int argsLength = ...; // Get length from the format's structure this.commandLineArguments = readUnicodeString(file, argsOffset, argsLength);Note: You’ll need to reference Microsoft’s official .lnk format specs to get the exact offsets and lengths for these fields.
Add Getter Methods
Expose the new data with getter methods:public String getCommandLineArguments() { return commandLineArguments; } public String getWorkingDirectory() { return workingDirectory; }
Option 2: Use Apache Commons Compress (No Custom Code Needed)
A far simpler approach is to use the LnkParser from Apache Commons Compress, which fully supports parsing all .lnk metadata out of the box.
Step 1: Add the Dependency
If you’re using Maven, add this to your pom.xml:
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-compress</artifactId> <version>1.24.0</version> <!-- Use the latest stable version --> </dependency>
Step 2: Extract the Data with Example Code
Here’s how to retrieve the full target (including arguments) and working directory:
import org.apache.commons.compress.archivers.lnk.LnkParser; import java.io.File; import java.io.FileInputStream; public class LnkMetadataExtractor { public static void main(String[] args) throws Exception { File lnkFile = new File("C:\\test\\test.lnk"); // Remember to escape backslashes in Java try (FileInputStream inputStream = new FileInputStream(lnkFile)) { LnkParser parser = new LnkParser(inputStream); // Get full target path + command-line arguments String fullTarget = parser.getLinkTargetIDList().getFullPath(); String arguments = parser.getCommandLineArguments(); if (arguments != null && !arguments.isEmpty()) { fullTarget += " " + arguments; } // Get working directory String workingDir = parser.getWorkingDirectory(); System.out.println("Full Target (with arguments): " + fullTarget); System.out.println("Working Directory: " + workingDir); } } }
This method avoids the hassle of manual format parsing and is maintained by a trusted open-source project, so it’s more reliable for long-term use.
内容的提问来源于stack exchange,提问作者fen

