from ctypes import * from ctypes.wintypes import DWORD, WIN32_FIND_DATAA, WIN32_FIND_DATAW, MAX_PATH from comtypes import IUnknown, GUID, COMMETHOD, HRESULT, CoClass # for GetPath SLGP_SHORTPATH = 0x1 SLGP_UNCPRIORITY = 0x2 SLGP_RAWPATH = 0x4 # for SetShowCmd, GetShowCmd ##SW_SHOWNORMAL ##SW_SHOWMAXIMIZED ##SW_SHOWMINNOACTIVE # for Resolve ##SLR_INVOKE_MSI ##SLR_NOLINKINFO ##SLR_NO_UI ##SLR_NOUPDATE ##SLR_NOSEARCH ##SLR_NOTRACK ##SLR_UPDATE # fake these... ITEMIDLIST = c_int LPITEMIDLIST = LPCITEMIDLIST = POINTER(ITEMIDLIST) class IShellLinkA(IUnknown): _iid_ = GUID('{000214EE-0000-0000-C000-000000000046}') _methods_ = [ COMMETHOD([], HRESULT, 'GetPath', ( ['in', 'out'], c_char_p, 'pszFile' ), ( ['in'], c_int, 'cchMaxPath' ), ( ['in', 'out'], POINTER(WIN32_FIND_DATAA), 'pfd' ), ( ['in'], DWORD, 'fFlags' )), COMMETHOD([], HRESULT, 'GetIDList', ( ['retval', 'out'], POINTER(LPITEMIDLIST), 'ppidl' )), COMMETHOD([], HRESULT, 'SetIDList', ( ['in'], LPCITEMIDLIST, 'pidl' )), COMMETHOD([], HRESULT, 'GetDescription', ( ['in', 'out'], c_char_p, 'pszName' ), ( ['in'], c_int, 'cchMaxName' )), COMMETHOD([], HRESULT, 'SetDescription', ( ['in'], c_char_p, 'pszName' )), COMMETHOD([], HRESULT, 'GetWorkingDirectory', ( ['in', 'out'], c_char_p, 'pszDir' ), ( ['in'], c_int, 'cchMaxPath' )), COMMETHOD([], HRESULT, 'SetWorkingDirectory', ( ['in'], c_char_p, 'pszDir' )), COMMETHOD([], HRESULT, 'GetArguments', ( ['in', 'out'], c_char_p, 'pszArgs' ), ( ['in'], c_int, 'cchMaxPath' )), COMMETHOD([], HRESULT, 'SetArguments', ( ['in'], c_char_p, 'pszArgs' )), COMMETHOD(['propget'], HRESULT, 'Hotkey', ( ['retval', 'out'], POINTER(c_short), 'pwHotkey' )), COMMETHOD(['propput'], HRESULT, 'Hotkey', ( ['in'], c_short, 'pwHotkey' )), COMMETHOD(['propget'], HRESULT, 'ShowCmd', ( ['retval', 'out'], POINTER(c_int), 'piShowCmd' )), COMMETHOD(['propput'], HRESULT, 'ShowCmd', ( ['in'], c_int, 'piShowCmd' )), COMMETHOD([], HRESULT, 'GetIconLocation', ( ['in', 'out'], c_char_p, 'pszIconPath' ), ( ['in'], c_int, 'cchIconPath' ), ( ['in', 'out'], POINTER(c_int), 'piIcon' )), COMMETHOD([], HRESULT, 'SetIconLocation', ( ['in'], c_char_p, 'pszIconPath' ), ( ['in'], c_int, 'iIcon' )), COMMETHOD([], HRESULT, 'SetRelativePath', ( ['in'], c_char_p, 'pszPathRel' ), ( ['in'], DWORD, 'dwReserved' )), COMMETHOD([], HRESULT, 'Resolve', ( ['in'], c_int, 'hwnd' ), ( ['in'], DWORD, 'fFlags' )), COMMETHOD([], HRESULT, 'SetPath', ( ['in'], c_char_p, 'pszFile' )), ] def GetPath(self, flags=SLGP_SHORTPATH): buf = create_string_buffer(MAX_PATH) # We're not interested in WIN32_FIND_DATA self.__com_GetPath(buf, MAX_PATH, None, flags) return buf.value def GetDescription(self): buf = create_string_buffer(1024) self.__com_GetDescription(buf, 1024) return buf.value def GetWorkingDirectory(self): buf = create_string_buffer(MAX_PATH) self.__com_GetWorkingDirectory(buf, MAX_PATH) return buf.value def GetArguments(self): buf = create_string_buffer(1024) self.__com_GetArguments(buf, 1024) return buf.value def GetIconLocation(self): iIcon = c_int() buf = create_string_buffer(MAX_PATH) self.__com_GetIconLocation(buf, MAX_PATH, byref(iIcon)) return buf.value, iIcon.value class IShellLinkW(IUnknown): _iid_ = GUID('{000214F9-0000-0000-C000-000000000046}') _methods_ = [ COMMETHOD([], HRESULT, 'GetPath', ( ['in', 'out'], c_wchar_p, 'pszFile' ), ( ['in'], c_int, 'cchMaxPath' ), ( ['in', 'out'], POINTER(WIN32_FIND_DATAW), 'pfd' ), ( ['in'], DWORD, 'fFlags' )), COMMETHOD([], HRESULT, 'GetIDList', ( ['retval', 'out'], POINTER(LPITEMIDLIST), 'ppidl' )), COMMETHOD([], HRESULT, 'SetIDList', ( ['in'], LPCITEMIDLIST, 'pidl' )), COMMETHOD([], HRESULT, 'GetDescription', ( ['in', 'out'], c_wchar_p, 'pszName' ), ( ['in'], c_int, 'cchMaxName' )), COMMETHOD([], HRESULT, 'SetDescription', ( ['in'], c_wchar_p, 'pszName' )), COMMETHOD([], HRESULT, 'GetWorkingDirectory', ( ['in', 'out'], c_wchar_p, 'pszDir' ), ( ['in'], c_int, 'cchMaxPath' )), COMMETHOD([], HRESULT, 'SetWorkingDirectory', ( ['in'], c_wchar_p, 'pszDir' )), COMMETHOD([], HRESULT, 'GetArguments', ( ['in', 'out'], c_wchar_p, 'pszArgs' ), ( ['in'], c_int, 'cchMaxPath' )), COMMETHOD([], HRESULT, 'SetArguments', ( ['in'], c_wchar_p, 'pszArgs' )), COMMETHOD(['propget'], HRESULT, 'Hotkey', ( ['retval', 'out'], POINTER(c_short), 'pwHotkey' )), COMMETHOD(['propput'], HRESULT, 'Hotkey', ( ['in'], c_short, 'pwHotkey' )), COMMETHOD(['propget'], HRESULT, 'ShowCmd', ( ['retval', 'out'], POINTER(c_int), 'piShowCmd' )), COMMETHOD(['propput'], HRESULT, 'ShowCmd', ( ['in'], c_int, 'piShowCmd' )), COMMETHOD([], HRESULT, 'GetIconLocation', ( ['in', 'out'], c_wchar_p, 'pszIconPath' ), ( ['in'], c_int, 'cchIconPath' ), ( ['in', 'out'], POINTER(c_int), 'piIcon' )), COMMETHOD([], HRESULT, 'SetIconLocation', ( ['in'], c_wchar_p, 'pszIconPath' ), ( ['in'], c_int, 'iIcon' )), COMMETHOD([], HRESULT, 'SetRelativePath', ( ['in'], c_wchar_p, 'pszPathRel' ), ( ['in'], DWORD, 'dwReserved' )), COMMETHOD([], HRESULT, 'Resolve', ( ['in'], c_int, 'hwnd' ), ( ['in'], DWORD, 'fFlags' )), COMMETHOD([], HRESULT, 'SetPath', ( ['in'], c_wchar_p, 'pszFile' )), ] def GetPath(self, flags=SLGP_SHORTPATH): buf = create_unicode_buffer(MAX_PATH) # We're not interested in WIN32_FIND_DATA self.__com_GetPath(buf, MAX_PATH, None, flags) return buf.value def GetDescription(self): buf = create_unicode_buffer(1024) self.__com_GetDescription(buf, 1024) return buf.value def GetWorkingDirectory(self): buf = create_unicode_buffer(MAX_PATH) self.__com_GetWorkingDirectory(buf, MAX_PATH) return buf.value def GetArguments(self): buf = create_unicode_buffer(1024) self.__com_GetArguments(buf, 1024) return buf.value def GetIconLocation(self): iIcon = c_int() buf = create_unicode_buffer(MAX_PATH) self.__com_GetIconLocation(buf, MAX_PATH, byref(iIcon)) return buf.value, iIcon.value class ShellLink(CoClass): 'ShellLink class' _reg_clsid_ = GUID('{00021401-0000-0000-C000-000000000046}') _idlflags_ = [] _com_interfaces_ = [IShellLinkW, IShellLinkA] if __name__ == "__main__": import sys import comtypes from comtypes.client import CreateObject from comtypes.persist import IPersistFile shortcut = CreateObject(ShellLink) print(shortcut) ##help(shortcut) shortcut.SetPath(sys.executable) shortcut.SetDescription("Python %s" % sys.version) shortcut.SetIconLocation(sys.executable, 1) print(shortcut.GetPath(2)) print(shortcut.GetIconLocation()) pf = shortcut.QueryInterface(IPersistFile) pf.Save("foo.lnk", True) print(pf.GetCurFile())