Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

can't run win_post_install from pip #2188

Closed
mikofski opened this issue Feb 22, 2015 · 10 comments · Fixed by #2377
Closed

can't run win_post_install from pip #2188

mikofski opened this issue Feb 22, 2015 · 10 comments · Fixed by #2377

Comments

@mikofski
Copy link
Contributor

please add this snippet to spyder_win_post_install.py to mimic bdist_wininst. I cribbed it from pywin32_post_install.py. Thanks!

try:
    # When this script is run from inside the bdist_wininst installer,
    # file_created() and directory_created() are additional builtin
    # functions which write lines to Python23\pywin32-install.log. This is
    # a list of actions for the uninstaller, the format is inspired by what
    # the Wise installer also creates.
    file_created
    is_bdist_wininst = True
except NameError:
    is_bdist_wininst = False # we know what it is not - but not what it is :)
    def file_created(file):
        pass
    def directory_created(directory):
        pass
    def get_root_hkey():
        try:
            winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE,
                           root_key_name, 0, winreg.KEY_CREATE_SUB_KEY)
            return winreg.HKEY_LOCAL_MACHINE
        except OSError, details:
            # Either not exist, or no permissions to create subkey means
            # must be HKCU
            return winreg.HKEY_CURRENT_USER

try:
    create_shortcut
except NameError:
    # Create a function with the same signature as create_shortcut provided
    # by bdist_wininst
    def create_shortcut(path, description, filename,
                        arguments="", workdir="", iconpath="", iconindex=0):
        import pythoncom
        from win32com.shell import shell, shellcon

        ilink = pythoncom.CoCreateInstance(shell.CLSID_ShellLink, None,
                                           pythoncom.CLSCTX_INPROC_SERVER,
                                           shell.IID_IShellLink)
        ilink.SetPath(path)
        ilink.SetDescription(description)
        if arguments:
            ilink.SetArguments(arguments)
        if workdir:
            ilink.SetWorkingDirectory(workdir)
        if iconpath or iconindex:
            ilink.SetIconLocation(iconpath, iconindex)
        # now save it.
        ipf = ilink.QueryInterface(pythoncom.IID_IPersistFile)
        ipf.Save(filename, 0)

    # Support the same list of "path names" as bdist_wininst.
    def get_special_folder_path(path_name):
        import pythoncom
        from win32com.shell import shell, shellcon

        for maybe in """
            CSIDL_COMMON_STARTMENU CSIDL_STARTMENU CSIDL_COMMON_APPDATA
            CSIDL_LOCAL_APPDATA CSIDL_APPDATA CSIDL_COMMON_DESKTOPDIRECTORY
            CSIDL_DESKTOPDIRECTORY CSIDL_COMMON_STARTUP CSIDL_STARTUP
            CSIDL_COMMON_PROGRAMS CSIDL_PROGRAMS CSIDL_PROGRAM_FILES_COMMON
            CSIDL_PROGRAM_FILES CSIDL_FONTS""".split():
            if maybe == path_name:
                csidl = getattr(shellcon, maybe)
                return shell.SHGetSpecialFolderPath(0, csidl, False)
        raise ValueError("%s is an unknown path ID" % (path_name,))
@ccordoba12
Copy link
Member

I'm afraid you're going to need to create a pull request, because this snippet is too big and some things seem to be repeated with our code.

@mikofski
Copy link
Contributor Author

This snippet checks if spyder is being installed from a bdist_wininst .exe archive on a Windows machine or something from else, eg pip. It checks for several attributes that are available when using bdist_wininst ie file_created, create_shortcut() and get_special_folder_path() and if it doesn't find them, creates dummy functions that do the same thing.

@ccordoba12
Copy link
Member

I understand now, but please do a pull request for this.

@ccordoba12
Copy link
Member

Could you also comment what's the exact problem that your snippet solves? Is it that you can't install Spyder on Windows using pip because of the lack of it?

@mikofski
Copy link
Contributor Author

On Windows, if user installs spyder using pip, then tries to run the win_post_install script, to add the start menu shortcuts which are quite nice, especially for less savvy, terminal-phobic users which spyder is a good choice for (ie: MATLAB converts), the user will get a nasty traceback because some of the module level attributes are only available when this script is part of a bdist_wininst

@mikofski
Copy link
Contributor Author

Would it be okay to make pywin32 a depndency on Windows systems? maybe something else already depends on pywin32?

@goanpeca goanpeca added this to the v3.0 milestone Apr 28, 2015
mikofski added a commit to mikofski/spyder that referenced this issue Apr 28, 2015
* add missing bdist_wininst functions from pywin32_postinstall.py:
 file_created(), directory_created(), get_root_key(), create_shortcut()
 and get_special_folder_path()
* test for pythoncom and return message "pywin32 required" on ImportError
* replace CSIDL_COMMON_PROGRAMS with CSIDL_PROGRAMS to be consistent with
 desktop shortcut which is in user profile, and so that user doesn't have
 to elevate rights in order to install spyder
* add TODO to remove error message "try running installer as
 administrator" since it's unnecessary if admin rights not required.
* if running spyder_win_post_install.py -install manually after installing
 with pip, then spyder.ico and spyder_light.ico are in the
 Python27\Scripts\ folder not in the distribution folder, so check if
 ico_dir exists and use absolute path to spyder_win_post_install.__file__
* clean up desktop and start menu shortcuts on removal
* provide feedback on successful removal of context, desktop and start
 menu shortcuts

Signed-off-by: Mark Mikofski <mark.mikofski@sunpowercorp.com>
@ccordoba12
Copy link
Member

@mikofski, unfortunately nothing else depends on pywin32 :-(

@mikofski
Copy link
Contributor Author

mikofski commented May 2, 2015

Does this mean that it can't be pulled? We can do it without pywin32, by using ctypes on ole32.dll and shell32.dll, which are both part of standard library, but it's a lot more work and I think most Windows users will already have Mark Hammond's pywin32 package.

@ccordoba12
Copy link
Member

Your pull request can be merged without problems because you added a message about pywin32 being required to run our post install script.

So if it's not found, the script will fail but people will know why :-)

@mikofski
Copy link
Contributor Author

mikofski commented May 4, 2015

Great, let me know if there's anything else you need.

@ccordoba12 ccordoba12 modified the milestones: v2.3.5, v3.0 Jun 1, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants