Стояла задача, распарсить произвольный ярлык который пользователь перетащит на форму, выдрав оттуда target, workdir, icon и прочее.
C этим вполне справлялась IShellLink, и вполне чудно работало, пока не столнулся с ярлыками МС Оффис 2010 и последним скайпом. Оказалось что у МС есть такая штука как Аdvertised shortcut,создаваемая WindowsInstaller-ом и которая поля “target” не имеет впринципе. как это работает написано тут https://support.microsoft.com/en-us/kb/243630. Соответвенно IShellLink возвращает вместо таргета путь к иконке.
в интернетах нашел vbs скрипт который получает правильный “target”. Пока в качестве временного решения вставил vbs . Может подскажете как сделать подобное на чистом питоне, без костылей??
Пока это выглядит так(кусок из проэкта):
........................................ winpath = os.path.normpath(filename) vbs = win32com.client.Dispatch("ScriptControl") vbs.language = "vbscript" scode=""" Option Explicit Function getTarget(path) Dim MSITarget With CreateObject("WindowsInstaller.Installer") Set MSITarget = .ShortcutTarget(path) getTarget = .ComponentPath(MSITarget.StringData(1), MSITarget.StringData(3)) End With End Function """ vbs.addcode(scode) command = 'getTarget('+'"'+winpath+'"'+')' try: # пробуем вызвать скрипт path = vbs.eval(command) except: # не получилось или это не advertised shortcut то пробуем стандартный метод через IShellLink path, _ = link.GetPath(shell.SLGP_UNCPRIORITY) ......................................
## -*- coding: utf-8 -*-
import win32com.client
import os
path = "c:/Users/UserName/Desktop/Microsoft Outlook 2010.lnk"
#path = "C:/Users/UserName/Desktop/notepad.lnk"
path = os.path.normpath(path)
vbs = win32com.client.Dispatch("ScriptControl")
vbs.language = "vbscript"
scode="""
Option Explicit
Function getTarget(path)
Dim MSITarget
On Error Resume Next ' just some simple error handling for purposes of this example
With CreateObject("WindowsInstaller.Installer")
Set MSITarget = .ShortcutTarget(path)
If Err = 0 then
getTarget = .ComponentPath(MSITarget.StringData(1), MSITarget.StringData(3))
Else
getTarget = path & " is not a legitimate MSI shortcut file or could not be found"
End If
End With
End Function
"""
vbs.addcode(scode)
command = 'getTarget("'+path+'")'
print(vbs.eval(command))
пробовал по аналогии с vbs проделать подобное через COM
## -*- coding: utf-8 -*- import win32com.client import os path = "c:/MicrosoftOutlook2010.lnk" path = os.path.normpath(path) msi = win32com.client.Dispatch('WindowsInstaller.Installer') MSITarget = msi.ShortcutTarget(path) #print(MSITarget)
Traceback (most recent call last):
File “D:\Python 3\advertise_shtcut2.py”, line 8, in <module>
MSITarget = msi.ShortcutTarget(path)
File “<COMObject WindowsInstaller.Installer>”, line 2, in ShortcutTarget
pywintypes.com_error: (-2147352573, ‘Член группы не найден.’, None, None)
Кда его далше копать ХЗ. с путями пробовал уже по всякому, и двойные слеши, и в кавычки заключать путь, все без толку.
UPD: возможно причина в том что ShortcutTarget возвращает тип Record?