How to create a shortcut in startmenu using setuptools windows installer

前端 未结 3 2128
说谎
说谎 2021-02-15 23:13

I want to create a start menu or Desktop shortcut for my Python windows installer package. I am trying to follow https://docs.python.org/3.4/distutils/builtdist.html#the-postins

3条回答
  •  南方客
    南方客 (楼主)
    2021-02-16 00:10

    At least with Python 3.6.5, 32bit on Windows, setuptools does work for this. But based on the accepted answer, by trial and error I found some issues that may have caused your script to fail to do what you wanted.

    1. create_shortcut does not accept keyword arguments, only positional, so its usage in your code is invalid
    2. You must add a .lnk extension for Windows to recognise the shortcut
    3. I found sys.executable will be the name of the installer executable, not the python executable
    4. As mentioned, you can't see stdout or stderr so you might want to log to a text file. I would suggest also redirecting sys.stdout and sys.stderr to the log file.
    5. (Maybe not relevant) as mentioned in this question there appears to be a bug with the version string generated by bdist_wininst. I used the hexediting hack from an answer there to work around this. The location in the answer is not the same, you have to find the -32 yourself.

    Full example script:

    import sys
    import os
    import datetime
    global datadir
    datadir = os.path.join(get_special_folder_path("CSIDL_APPDATA"), "mymodule")
    def main(argv):
        if "-install" in argv:
            desktop = get_special_folder_path("CSIDL_DESKTOPDIRECTORY")
            print("Desktop path: %s" % repr(desktop))
            if not os.path.exists(datadir):
                os.makedirs(datadir)
                dir_created(datadir)
                print("Created data directory: %s" % repr(datadir))
            else:
                print("Data directory already existed at %s" % repr(datadir))
    
            shortcut = os.path.join(desktop, "MyModule.lnk")
            if os.path.exists(shortcut):
                print("Remove existing shortcut at %s" % repr(shortcut))
                os.unlink(shortcut)
    
            print("Creating shortcut at %s...\n" % shortcut)
            create_shortcut(
                r'C:\Python36\python.exe',
                "MyModuleScript",
                shortcut, 
                "",
                datadir)
            file_created(shortcut)
            print("Successfull!")
        elif "-remove" in sys.argv:
            print("Removing...")
            pass
    
    
    if __name__ == "__main__":
        logfile = r'C:\mymodule_install.log' # Fallback location
        if os.path.exists(datadir):
            logfile = os.path.join(datadir, "install.log")
        elif os.environ.get("TEMP") and os.path.exists(os.environ.get("TEMP"),""):
            logfile = os.path.join(os.environ.get("TEMP"), "mymodule_install.log")
    
        with open(logfile, 'a+') as f:
            f.write("Opened\r\n")
            f.write("Ran %s %s at %s" % (sys.executable, " ".join(sys.argv), datetime.datetime.now().isoformat()))
            sys.stdout = f
            sys.stderr = f
            try:
                main(sys.argv)
            except Exception as e:
                raise
            f.close()
    
        sys.exit(0)
    

提交回复
热议问题