Java 中的 Windows 快捷方式 (.lnk) 解析器?
我目前正在使用 Win32ShellFolderManager2
和 ShellFolder.getLinkLocation
来解析 Java 中的 Windows 快捷方式。 不幸的是,如果 Java 程序在 Vista 下作为服务运行,getLinkLocation
则不起作用。 具体来说,我收到一个异常,指出“无法获取 shell 文件夹 ID 列表”。
搜索网络确实会提到此错误消息,但总是与 JFileChooser
有关。 我没有使用 JFileChooser
,我只需要将 .lnk
文件解析到其目的地。
有谁知道我可以使用用 Java 编写的 .lnk 文件的第 3 方解析器吗?
I'm currently using Win32ShellFolderManager2
and ShellFolder.getLinkLocation
to resolve windows shortcuts in Java. Unfortunately, if the Java program is running as a service under Vista, getLinkLocation
, this does not work. Specifically, I get an exception stating "Could not get shell folder ID list".
Searching the web does turn up mentions of this error message, but always in connection with JFileChooser
. I'm not using JFileChooser
, I just need to resolve a .lnk
file to its destination.
Does anyone know of a 3rd-party parser for .lnk
files written in Java I could use?
I've since found unofficial documentation for the .lnk format here, but I'd rather not have to do the work if anyone has done it before, since the format is rather scary.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
使用
mslinks
库mslinks 是一个开源、维护良好、良好的已测试的项目,其作者投入了大量精力对快捷方式格式进行逆向工程。 考虑使用它来代替答案中列出的任何代码。
如果该库不适合您的需求,请继续阅读...
来自各种其他答案的代码
我组合了来自各种答案的一些代码,并添加了注释(一些解释以及到目前为止对每个贡献者的认可),其他检查文件魔法,快速测试以查看给定文件是否可能是有效链接(无需读取所有字节),修复如果文件太小并执行了一些操作,则抛出带有适当消息的 ParseException 而不是 ArrayIndexOutOfBoundsException一般清理。
来源此处(如果您有任何更改) ,将它们直接推送到 GitHub repo/项目。
Use
mslinks
librarymslinks is an open source, well-maintained, well-tested project whose author has put considerable effort into reverse-engineering the shortcut format. Consider using it instead of any of the code listed in the answers.
If that library does not suit your needs, read on...
Code from various other answers
I've combined some of the code from the various answers, and added comments (some explanation as well as credit to each contributor so far), additional check on the file magic, a quick test to see if a given file might be a valid link (without reading all of the bytes), a fix to throw a ParseException with appropriate message instead of ArrayIndexOutOfBoundsException if the file is too small and did some general clean-up.
Source here (if you have any changes, push them right to the GitHub repo/project.
Sam Brightman 的解决方案仅适用于本地文件。
我添加了对网络文件的支持:
http ://www.javafaq.nu/java-example-code-468.html
Sam Brightman's solution is for local files only.
I added support for Network files:
http://www.javafaq.nu/java-example-code-468.html
我可以在 GitHub 上推荐这个存储库:
https://github.com/BlackOverlord666/mslinks
在那里我找到了一个创建快捷方式的简单解决方案:
ShellLink.createLink("path/to/existing/file.txt", "path/to/the/future/shortcut.lnk");
如果您想阅读快捷方式:
如果您想更改快捷方式的图标,请使用:
您可以编辑快捷方式链接的大多数属性,例如工作目录、工具提示文本、图标、命令行参数、热键、创建指向的链接LAN 共享文件和目录 等等...
希望这对您有帮助:)
亲切的问候
乔苏亚·弗兰克
I can recommend 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:
If you want to change the icon of the shortcut, use:
You can edit most properties of the shortcutlink such as working directory, tooltip text, icon, command line arguments, hotkeys, create links to LAN shared files and directories and much more...
Hope this helps you :)
Kind regards
Josua Frank
链接到的代码 plan9assembler 似乎只需稍作修改即可工作。 我认为这只是“
& 0xff
”,以防止当byte
在bytes2short< 中将
byte
向上转换为int
时进行符号扩展/code> 需要更改的功能。 我添加了 http://www.i2s-lab.com/ 中描述的功能Papers/The_Windows_Shortcut_File_Format.pdf 连接“路径名的最后部分”,尽管在实践中这似乎没有在我的示例中使用。 我没有向标头添加任何错误检查或处理网络共享。 这是我现在使用的:The code plan9assembler linked to appears to work with minor modification. I think it's just the "
& 0xff
" to prevent sign extension whenbyte
s are upcast toint
s in thebytes2short
function that need changing. I've added the functionality described in http://www.i2s-lab.com/Papers/The_Windows_Shortcut_File_Format.pdf to concatenate the "final part of the pathname" even though in practice this doesn't seem to be used in my examples. I've not added any error checking to the header or dealt with network shares. Here's what I'm using now:我也在 Java 中的“.lnk”上工作过(现在没有时间)。 我的代码是 here
这有点混乱(一些测试垃圾),但本地和网络解析效果很好。 创建链接也已实现。 请测试并向我发送补丁。
解析示例:
创建新链接:
I've also worked( now have no time for that) on '.lnk' in Java. My code is here
It's little messy( some testing trash) but local and network parsing works good. Creating links is implemented too. Please test and send me patches.
Parsing example:
Creating new link:
@Code Bling 的解决方案对于用户目录中的文件不适用于我。
例如“C:/Users/用户名/文件名.txt”。
原因是:在 The_Windows_Shortcut_File_Format.pdf
@Stefan Cordes 在第 6 页提到,它表示只有前 2 位对于卷信息很重要。
当卷信息的第一位为“0”时,所有其他位可能会被随机垃圾填充。
因此,如果涉及到:
那么
file_location_info_flag
可能是“3”。该文件仍然是本地文件,但是这行代码将
false
分配给isLocal
。所以我建议对@Code Bling的代码进行以下调整:
The solution of @Code Bling does not work for me for Files in the User directory.
For Example "C:/Users/Username/Filename.txt".
The reason for that is: in The_Windows_Shortcut_File_Format.pdf
that was mentioned by @Stefan Cordes on page 6 it says that only the first 2 bits are important for volumes info.
All other bits might be filled with random garbage when the first bit of volumes info is "0".
So if it comes to:
then
file_location_info_flag
might be "3".This file is still local but this line of code assigns
false
toisLocal
.So i suggest the following adjustment to @Code Bling's code:
这段简短的代码确实有用...
但需要两个修复:
改进了 isPotentialValidLink,如果名称不以“.lnk”结尾,则不会加载文件
偏移量必须使用 32 位计算,而不仅仅是一个字节...
This short code is really usefull...
But two fixes are needed:
the isPotentialValidLink improved not to load file if name doesn't end with ".lnk"
the offset has to be computed with 32bits not only a byte...
我发现了其他非专业技术。 完成我的工作。
I found other non-professional technique. getting my job done.
给定的代码运行良好,但有一个错误。 java字节是从-128到127的有符号值。我们想要从0到255的无符号值以获得正确的结果。 只需将 bytes2short 函数更改如下:
The given code works well, but has a bug. A java byte is a signed value from -128 to 127. We want an unsigned value from 0 to 255 to get the correct results. Just change the bytes2short function as follows: