Получить путь к исполняемому файлу из меню «Пуск» Windows с помощью Python

#python #python-3.x #windows #subprocess

Вопрос:

Я разрабатываю удобную для пользователя программу из колледжа, и мы хотели, чтобы наш скрипт на Python открывал программу для пользователя. Большинство пользователей не будут точно знать, где хранятся их исполняемые файлы, поэтому нам было интересно, есть ли способ получить нужные нам пути через меню «Пуск» Windows? (Каждая программа, которая отображается при поиске в Windows, имеет ярлык, сохраненный в меню «Пуск»). Спасибо за ваше время! 🙂

Комментарии:

1. Разве «Пуск» не является собственной папкой в Windows? Если это так, создайте pathlib. Путь к любой символической ссылке, содержащейся внутри, и вызовите ее метод resolve (). Я бы написал ответ, но я не могу проверить это на iPhone.

2. docs.python.org/3/library/pathlib.html#methods

Ответ №1:

Я смог придумать грубое решение, основанное на некоторых других ответах:

 def get_shortcut_path(path: str) -> str:
    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 amp; 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])
        
        return target

def get_exe_path(app: str) -> str:
    username = getpass.getuser()
    start_menu = f'C:\Users\{username}\AppData\Roaming\Microsoft\Windows\Start Menu\Programs'
    
    for subdir, dirs, files in os.walk(start_menu):
        if not(subdir.startswith('Windows')):
            for file in files:
                if file.endswith('.lnk'):
                    print(get_shortcut_path(f'{subdir}/{file}'))