You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
218 lines
8.0 KiB
218 lines
8.0 KiB
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())
|