通过快捷方式.lnk获得文件真实路径
前提
最近开发资源管理,需要预先上传大量资源,负责整理资源的同学因为空间不足,直接用快捷键方式整理视频资源OTZ,所以只能想办法通过.lnk文件获得文件的真实地址。

以下所有内容都来自网络,博主仅做了参考与总结。

.lnk文件格式解析
此处对lnk文件组成做一个大概介绍主旨是帮助了解如何从link文件中提取需要的信息
一个lnk文件包括一下几个模块:

模块 备注

注意:
不是所有的模块都必须包含在内,但如果存在就要按上述的顺序排列。

以下我们详细了解需要用到的两个模块:
1. 文件头(lnk file header)

偏移 长度 类型 备注

0x14处16进制数的含义:

0x18处16进制数的含义:

2. 文件位置信息段(File location info)

0x08偏移flags 具体含义:

如果目标文件是本地文件,那么文件名称 = 本地路径信息+剩余偏移路径
如果目标文件是网络文件,那么文件名称 = 网络卷中共享名称+剩余偏移路径
所以,File location info节之后的数据是,本地卷信息表,及网络卷信息表。
1. 本地卷信息表结构

2. 网络卷信息表结构

注意:
八个比特(Bit)称为一个字节(Byte),两个字节称为一个字(Word),两个字称为一个双字(Dword),两个双字称为一个四字(Qword)。

代码

private void parseLink(File f) throws FileNotFoundException, IOException {
FileInputStream fin = new FileInputStream(f);
byte[] link = new byte[(int)f.length()];
//读取文件中的内容到link[]数组
fin.read(link);
fin.close(); // 判断当前文件是否为快捷方式
if(!isLnkFile(link)){
return;
}
// 获得flags信息
byte flags = link[0x14]; int shell_len = 0;
// 0000 0000 xxxx xxxx & 0000 0000 0000 0001(判断是否包含shell item id list段)
if((flags & 0x1) > 0) {
// 如果存在,则获取shell item id list段的总长度,加2是为了将link[0x4c]本身的长度计算在内
shell_len = bytes2short(link,0x4c) + 2;
}
// 获得文件位置信息段的开始位置=shell item id list段的开始位置+shell item id list段的总长度
int file_start = 0x4c + shell_len;
// 获取本地路径信息的偏移
int local_sys_off = link[file_start + 0x10] + file_start;
String real_file = getNullDelimitedString(link, local_sys_off);
System.out.println(real_file);
} private boolean isLnkFile(byte[] link) {
if (link[0x00]== 0x4c) {// 76,L,0x4c代表lnk文件格式
return true;
}
return false;
} /**
* 将两个字节转换为short<br>
* 注意,因为仅限英特尔操作系统,所以这是小端字节<br>
*/
private int bytes2short(byte[] bytes, int off) {
return bytes[off] | (bytes[off + 1] << 8);
} /**
* 获得从偏移位置off到以‘0’为结尾分割字符串
* @param bytes 源数组
* @param off 偏移位置
* @return 字符串
*/
private String getNullDelimitedString(byte[] bytes, int off) {
int len = 0;
// 计算字符串占用数组的真实长度
while (true) {
if (bytes[off + len] == 0) {
break;
}
len++;
}
byte[] results = new byte[len];
for (int i = off, j = 0; i < off + len; i++, j++) {
results[j] = bytes[i];
}
try {
// 因为我是中文系统,所以设置了字符集GBK,否则中文路径会出现乱码
return new String(bytes, off, len, "GBK");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}

  

import sys
import win32com.client shell = win32com.client.Dispatch("WScript.Shell")
shortcut = shell.CreateShortCut("t:\\test.lnk")
print(shortcut.Targetpath)

  

最新文章

  1. IOS开发基础知识--碎片6
  2. BZOJ1093 [ZJOI2007]最大半连通子图
  3. 利用Kinect将投影变得可直接用手操控
  4. 动态规划 求解 Minimum Edit Distance
  5. ASP.NET Cookie存值问题
  6. Linux 相关基础笔记
  7. ahjesus sql手动重新更新ID
  8. jQuery的弹出窗口插件colorbox
  9. 【BZOJ】【1430】小猴打架
  10. Inside Microsoft SQL Server 2008: T-SQL Querying 读书笔记之查询优化
  11. 【原】数据库SQL语句入门
  12. C++的常量折叠(二)
  13. Win7怎么把运行添加到Win快捷菜单的右侧、、、
  14. 内核kmalloc内存越界排查过程(转)
  15. CentOS7 yum安装配置 drbd-84-utils (外部模式)
  16. ubuntu 14.04 安装python包psycopg2
  17. asp.net json,对象,字符串的相互转换
  18. 获取当前页面url
  19. 【HDOJ4109】【拓扑OR差分约束求关键路径】
  20. Swift 属性 函数

热门文章

  1. 【Unsolved】线性时间选择算法的复杂度证明
  2. 使用canal通过mysql复制协议从binlog实现热数据nosql缓存(1)
  3. Win10 企业版 激活 批处理
  4. C++结构体基础知识
  5. NDK学习笔记-JNI的异常处理与缓存策略
  6. 在VMware上安装centos
  7. vue用echarts 画3d地球 且画线
  8. python 1秒启动一个下载服务器
  9. [转帖]postgresql查看用户连接以及杀死连接的会话
  10. Spring4学习回顾之路09-基于注解的方式配置bean