--- a/install.py Thu Sep 20 19:48:56 2018 +0200 +++ b/install.py Fri Sep 21 20:21:31 2018 +0200 @@ -732,24 +732,41 @@ """ Clean up the Desktop and Start Menu entries for Windows. """ - regPath = r"Software\Microsoft\Windows\CurrentVersion\Explorer" \ - r"\User Shell Folders" + try: + from pywintypes import com_error # __IGNORE_WARNING__ + except ImportError: + # links were not created by install.py + return + + regPath = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer" + \ + "\\User Shell Folders" + # 1. cleanup desktop links regName = "Desktop" - desktopFolder = os.path.normpath( - os.path.expandvars(getWinregEntry(regName, regPath))) - for linkName in windowsDesktopNames(): - linkPath = os.path.join(desktopFolder, linkName) - if os.path.exists(linkPath): - os.remove(linkPath) + desktopEntry = getWinregEntry(regName, regPath) + if desktopEntry: + desktopFolder = os.path.normpath(os.path.expandvars(desktopEntry)) + for linkName in windowsDesktopNames(): + linkPath = os.path.join(desktopFolder, linkName) + if os.path.exists(linkPath): + try: + os.remove(linkPath) + except EnvironmentError: + # maybe restrictions prohibited link removal + print("Could not remove '{0}'.".format(linkPath)) # 2. cleanup start menu entry regName = "Programs" - programsFolder = os.path.normpath( - os.path.expandvars(getWinregEntry(regName, regPath))) - eric6EntryPath = os.path.join(programsFolder, windowsProgramsEntry()) - if os.path.exists(eric6EntryPath): - shutil.rmtree(eric6EntryPath) + programsEntry = getWinregEntry(regName, regPath) + if programsEntry: + programsFolder = os.path.normpath(os.path.expandvars(programsEntry)) + eric6EntryPath = os.path.join(programsFolder, windowsProgramsEntry()) + if os.path.exists(eric6EntryPath): + try: + shutil.rmtree(eric6EntryPath) + except EnvironmentError: + # maybe restrictions prohibited link removal + print("Could not remove '{0}'.".format(eric6EntryPath)) def shutilCopy(src, dst, perm=0o644): @@ -949,11 +966,11 @@ createLinuxSpecifics() # Create Desktop and Start Menu entries for Windows systems - if sys.platform.startswith(("win", "cygwin")): + elif sys.platform.startswith(("win", "cygwin")): createWindowsLinks() # Create a Mac application bundle - if sys.platform == "darwin": + elif sys.platform == "darwin": createMacAppBundle(cfg['ericDir']) return 0 @@ -1084,7 +1101,8 @@ Create Desktop and Start Menu links. """ try: - from win32com.client import Dispatch + # check, if pywin32 is available + from win32com.client import Dispatch # __IGNORE_WARNING__ except ImportError: print( "\nThe Python package 'pywin32' is not installed. Desktop and" @@ -1092,7 +1110,33 @@ ) return - # TODO: create the windows desktop links and start menu entries + regPath = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer" + \ + "\\User Shell Folders" + + # 1. create desktop shortcuts + regName = "Desktop" + desktopFolder = os.path.normpath( + os.path.expandvars(getWinregEntry(regName, regPath))) + for linkName, targetPath, iconPath in windowsDesktopEntries(): + linkPath = os.path.join(desktopFolder, linkName) + createWindowsShortcut(linkPath, targetPath, iconPath) + + # 2. create start menu entry and shortcuts + regName = "Programs" + programsEntry = getWinregEntry(regName, regPath) + if programsEntry: + programsFolder = os.path.normpath(os.path.expandvars(programsEntry)) + eric6EntryPath = os.path.join(programsFolder, windowsProgramsEntry()) + if not os.path.exists(eric6EntryPath): + try: + os.makedirs(eric6EntryPath) + except EnvironmentError: + # maybe restrictions prohibited link creation + return + + for linkName, targetPath, iconPath in windowsDesktopEntries(): + linkPath = os.path.join(eric6EntryPath, linkName) + createWindowsShortcut(linkPath, targetPath, iconPath) def createMacAppBundle(pydir): @@ -1668,8 +1712,14 @@ @return value of requested registry variable @rtype any """ - # From http://stackoverflow.com/a/35286642 - import winreg + try: + import _winreg as winreg + except ImportError: + try: + import winreg + except ImportError: + return None + try: registryKey = winreg.OpenKey(winreg.HKEY_CURRENT_USER, path, 0, winreg.KEY_READ) @@ -1680,6 +1730,32 @@ return None +def createWindowsShortcut(linkPath, targetPath, iconPath): + """ + Create Windows shortcut. + + @param linkPath path of the shortcut file + @type str + @param targetPath path the shortcut shall point to + @type str + @param iconPath path of the icon file + @type str + """ + from win32com.client import Dispatch + from pywintypes import com_error + + try: + shell = Dispatch('WScript.Shell') + shortcut = shell.CreateShortCut(linkPath) + shortcut.Targetpath = targetPath + shortcut.WorkingDirectory = os.path.dirname(targetPath) + shortcut.IconLocation = iconPath + shortcut.save() + except com_error: + # maybe restrictions prohibited link creation + pass + + def windowsDesktopNames(): """ Function to generate the link names for the Windows Desktop. @@ -1687,13 +1763,47 @@ @return list of desktop link names @rtype list of str """ + return [e[0] for e in windowsDesktopEntries()] + + +def windowsDesktopEntries(): + """ + Function to generate data for the Windows Desktop links. + + @return list of tuples containing the desktop link name, + the link target and the icon target + @rtype list of tuples of (str, str, str) + """ + global cfg, includePythonVariant + + if includePythonVariant: + marker = PythonMarkers[sys.version_info.major] + else: + marker = "" + majorVersion, minorVersion = sys.version_info[:2] - linkTemplates = [ - "eric6 (Python {0}.{1}).lnk", - "eric6 Browser (Python {0}.{1}).lnk", + entriesTemplates = [ + ("eric6 (Python {0}.{1}).lnk", + os.path.join(cfg["bindir"], "eric6" + marker + ".cmd"), + os.path.join(cfg["ericPixDir"], "eric6.ico")), ] + if sys.version_info.major == 2: + entriesTemplates.append(( + "eric6 Browser (Python {0}.{1}).lnk", + os.path.join(cfg["bindir"], "eric6_webbrowser" + marker + ".cmd"), + os.path.join(cfg["ericPixDir"], "ericWeb48.ico") + )) + else: + entriesTemplates.append(( + "eric6 Browser (Python {0}.{1}).lnk", + os.path.join(cfg["bindir"], "eric6_browser" + marker + ".cmd"), + os.path.join(cfg["ericPixDir"], "ericWeb48.ico") + )) - return [l.format(majorVersion, minorVersion) for l in linkTemplates] + return [ + (e[0].format(majorVersion, minorVersion), e[1], e[2]) + for e in entriesTemplates + ] def windowsProgramsEntry():