1010from pathlib import Path
1111import importlib .util
1212import winreg
13- from winpython import utils
13+ from . import utils
1414from argparse import ArgumentParser
1515
16+ def get_special_folder_path (path_name ):
17+ """Return special folder path."""
18+ from win32com .shell import shell , shellcon
19+ try :
20+ csidl = getattr (shellcon , path_name )
21+ return shell .SHGetSpecialFolderPath (0 , csidl , False )
22+ except OSError :
23+ print (f"{ path_name } is an unknown path ID" )
24+
25+ def get_winpython_start_menu_folder (current = True ):
26+ """Return WinPython Start menu shortcuts folder."""
27+ folder = get_special_folder_path ("CSIDL_PROGRAMS" )
28+ if not current :
29+ try :
30+ folder = get_special_folder_path ("CSIDL_COMMON_PROGRAMS" )
31+ except OSError :
32+ pass
33+ return str (Path (folder ) / 'WinPython' )
34+
35+ def remove_winpython_start_menu_folder (current = True ):
36+ """Remove WinPython Start menu folder -- remove it if it already exists"""
37+ path = get_winpython_start_menu_folder (current = current )
38+ if Path (path ).is_dir ():
39+ try :
40+ shutil .rmtree (path , onexc = onerror )
41+ except WindowsError :
42+ print (f"Directory { path } could not be removed" , file = sys .stderr )
43+
44+ def create_winpython_start_menu_folder (current = True ):
45+ """Create WinPython Start menu folder."""
46+ path = get_winpython_start_menu_folder (current = current )
47+ if Path (path ).is_dir ():
48+ try :
49+ shutil .rmtree (path , onexc = onerror )
50+ except WindowsError :
51+ print (f"Directory { path } could not be removed" , file = sys .stderr )
52+ Path (path ).mkdir (parents = True , exist_ok = True )
53+ return path
54+
55+ def create_shortcut (path , description , filename , arguments = "" , workdir = "" , iconpath = "" , iconindex = 0 , verbose = True ):
56+ """Create Windows shortcut (.lnk file)."""
57+ import pythoncom
58+ from win32com .shell import shell
59+ ilink = pythoncom .CoCreateInstance (shell .CLSID_ShellLink , None , pythoncom .CLSCTX_INPROC_SERVER , shell .IID_IShellLink )
60+ ilink .SetPath (path )
61+ ilink .SetDescription (description )
62+ if arguments :
63+ ilink .SetArguments (arguments )
64+ if workdir :
65+ ilink .SetWorkingDirectory (workdir )
66+ if iconpath or iconindex :
67+ ilink .SetIconLocation (iconpath , iconindex )
68+ # now save it.
69+ ipf = ilink .QueryInterface (pythoncom .IID_IPersistFile )
70+ if not filename .endswith ('.lnk' ):
71+ filename += '.lnk'
72+ if verbose :
73+ print (f'create menu *{ filename } *' )
74+ try :
75+ ipf .Save (filename , 0 )
76+ except :
77+ print ("a fail !" )
1678
1779# --- Helper functions for Registry ---
1880
@@ -53,7 +115,7 @@ def _has_pywin32():
53115def _remove_start_menu_folder (target , current = True , has_pywin32 = False ):
54116 "remove menu Folder for target WinPython if pywin32 exists"
55117 if has_pywin32 :
56- utils . remove_winpython_start_menu_folder (current = current )
118+ remove_winpython_start_menu_folder (current = current )
57119 else :
58120 print ("Skipping start menu removal as pywin32 package is not installed." )
59121
@@ -68,7 +130,7 @@ def _get_shortcut_data(target, current=True, has_pywin32=False):
68130 bname , ext = Path (name ).stem , Path (name ).suffix
69131 if ext .lower () == ".exe" :
70132 # Path for the shortcut file in the start menu folder
71- shortcut_name = str (Path (utils . create_winpython_start_menu_folder (current = current )) / bname ) + '.lnk'
133+ shortcut_name = str (Path (create_winpython_start_menu_folder (current = current )) / bname ) + '.lnk'
72134 data .append (
73135 (
74136 str (Path (wpdir ) / name ), # Target executable path
@@ -180,9 +242,9 @@ def register(target, current=True, reg_type=winreg.REG_SZ, verbose=True):
180242 print (f'Creating WinPython menu for all icons in { target .parent } ' )
181243 for path , desc , fname in _get_shortcut_data (target , current = current , has_pywin32 = True ):
182244 try :
183- utils . create_shortcut (path , desc , fname , verbose = verbose )
245+ create_shortcut (path , desc , fname , verbose = verbose )
184246 except Exception as e :
185- print (f"Error creating shortcut for { desc } at { fname } : { e } " , file = sys .stderr )
247+ print (f"Error creating shortcut for { desc } at { fname } : { e } " , file = sys .stderr )
186248 else :
187249 print ("Skipping start menu shortcut creation as pywin32 package is needed." )
188250
0 commit comments