Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reading the target of a .lnk file in Python?

I'm trying to read the target file/directory of a shortcut (.lnk) file from Python. Is there a headache-free way to do it? The spec is way over my head. I don't mind using Windows-only APIs.

My ultimate goal is to find the "(My) Videos" folder on Windows XP and Vista. On XP, by default, it's at %HOMEPATH%\My Documents\My Videos, and on Vista it's %HOMEPATH%\Videos. However, the user can relocate this folder. In the case, the %HOMEPATH%\Videos folder ceases to exists and is replaced by %HOMEPATH%\Videos.lnk which points to the new "My Videos" folder. And I want its absolute location.

like image 693
Etienne Perot Avatar asked Dec 29 '08 04:12

Etienne Perot


People also ask

How do you read a .LNK file?

How to open an LNK file. Opening an LNK file, by double-clicking it or right-clicking it and selecting Open, opens the file, folder, or program to which the LNK file points. Advanced users can edit an LNK file's properties by right-clicking the file and selecting Properties.

How do you find the location of a .LNK file?

Normally, most of LNK-files are located on the following paths: For Windows 7 to 10: C:\Users\%USERNAME%\AppData\Roaming\Microsoft\Windows\Recent. For Windows XP: C:\Documents and Settings\%USERNAME%\Recent.

How do I unpack an LNK file?

Just drag and drop them into the Notepad window. If you open them via the Open dialog, Notepad will open the exe file pointed to by the . lnk file.

What information does a LNK file contain?

An LNK file is a Windows Shortcut that serves as a pointer to open a file, folder, or application. LNK files are based on the Shell Link binary file format, which holds information used to access another data object.


2 Answers

Create a shortcut using Python (via WSH)

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


Read the Target of a Shortcut using Python (via WSH)

import sys import win32com.client   shell = win32com.client.Dispatch("WScript.Shell") shortcut = shell.CreateShortCut("t:\\test.lnk") print(shortcut.Targetpath) 
like image 146
SaoPauloooo Avatar answered Oct 11 '22 08:10

SaoPauloooo


I know this is an older thread but I feel that there isn't much information on the method that uses the link specification as noted in the original question.

My shortcut target implementation could not use the win32com module and after a lot of searching, decided to come up with my own. Nothing else seemed to accomplish what I needed under my restrictions. Hopefully this will help other folks in this same situation.

It uses the binary structure Microsoft has provided for MS-SHLLINK.

import struct  path = 'myfile.txt.lnk'     target = ''  with open(path, 'rb') as stream:     content = stream.read()     # skip first 20 bytes (HeaderSize and LinkCLSID)     # read the LinkFlags structure (4 bytes)     lflags = struct.unpack('I', content[0x14:0x18])[0]     position = 0x18     # if the HasLinkTargetIDList bit is set then skip the stored IDList      # structure and header     if (lflags & 0x01) == 1:         position = struct.unpack('H', content[0x4C:0x4E])[0] + 0x4E     last_pos = position     position += 0x04     # get how long the file information is (LinkInfoSize)     length = struct.unpack('I', content[last_pos:position])[0]     # skip 12 bytes (LinkInfoHeaderSize, LinkInfoFlags, and VolumeIDOffset)     position += 0x0C     # go to the LocalBasePath position     lbpos = struct.unpack('I', content[position:position+0x04])[0]     position = last_pos + lbpos     # read the string at the given position of the determined length     size= (length + last_pos) - position - 0x02     temp = struct.unpack('c' * size, content[position:position+size])     target = ''.join([chr(ord(a)) for a in temp]) 
like image 23
Jared Avatar answered Oct 11 '22 06:10

Jared