newville / pyshortcuts

create desktop shortcuts to python scripts on Windows, Mac, or Linux
https://newville.github.io/pyshortcuts
MIT License
105 stars 15 forks source link

Command line window #20

Open BjornFJohansson opened 5 years ago

BjornFJohansson commented 5 years ago

Great tool! This should be in the python standard library! I have been looking for this a long time. However, I still get a terminal when trying this on Windows using the terminal=False option. I looked at the code and I assume that wscript is not used to run the python script?

I have an app installed in an Anaconda environment, and the I manually create this vbs file:

Set oShell = CreateObject("WScript.Shell")
oShell.Run "cmd /C C:\Users\Utilizador\Anaconda3\Scripts\activate WIKIDPAD37 & C:\Users\Utilizador\Anaconda3\envs\WIKIDPAD37\Scripts\wikidpad.exe", false

Which actually works, no terminal is shown. The wikidpad.exe is an entry point created by setuptools. On the same installation I used pyshortcut:

make_shortcut( script='C:\\Users\\Utilizador\\Anaconda3\\envs\\WIKIDPAD37\\Scripts\\wikidpad',
               name='wikidpadmp',
               terminal=False,
               icon='C:\\Users\\Utilizador\\Anaconda3\\envs\\WIKIDPAD37\\Lib\\sitepackages\\WikidPad\\wikidpad.ico')

This also works although I have some path issues and the fact that a command line window is shown. Is this a bug or do I have to do something else?

Thanks for your time.

newville commented 5 years ago

@BjornFJohansson Hm, I'm not certain what oShell.run does differently.

But: we do only use the terminal argument to chose between python.exe and pythonw.exe, which can (and often will be) thrown away if using an exe as generated for a "console script".

I don't know the details of how pythonw.exe and python.exe differ, or the details of how "console script"-to-exe works.

Perhaps we should prefer running pythonw.exe Scripts\app-script.py over Scripts\app.exe?

Another possibility: we have wscript.WindowStyle hardwired to 0. From random googling, it looks like this can be set to 7 to mean "run in a minimized window". That's probably a better meaning of "terminal=False", but it isn't exactly the same as running without a console.

newville commented 5 years ago

@BjornFJohansson Just a bit of follow up after testing on a Windows machine:

I think that we may want explicit documentation and perhaps a change in behavior on this.
For app.py, we could be running

  1. C:\\Scripts\app.exe # Current
  2. C:\\pythonw.exe C:\\Scripts\app-script.py # force as GUI
  3. C:\\python.exe C:\\Scripts\app-script.py # force as console

I think "1" and "2" will be the same if app.py is declared as a gui_script entry point, but that the .exe version will show a Command terminal if app.py is declared as a console_script entry point.

That is, running the exe version sort of does "what you said" but it may not do "what you mean" for a GUI script.

What if we have it so that if you say "terminal=True", then you want to run as a console script (option 3), if you say "terminal=False" you want to run as a GUI script without a console (option 2) and if you have terminal=None that the .exe version (option 1) is preferred. That would mean changing the default terminal value to None to mean "run the .exe if available"

Does that seem reasonable?

maphew commented 5 years ago

this might be a side effect of the new enhamcement to use a batch file to set conda env before launching

BjornFJohansson commented 5 years ago

@newville I think that would be a nice way to squeeze the new functionality into the existing API. Does it also work in combination with the activation of the environment that happens before? I could try it out if needed.

@maphew do you mean the unexpected (for me) opening of a terminal window or the path issues?

newville commented 5 years ago

@BjornFJohansson @maphew I believe that using envrunner.bat .... as the shortcut target would have to invoke a Command window. That could be set to run as "minimized", or try some trick to a batch file without a command window....

maphew commented 5 years ago

There are number of methods listed on Raymond.cc, but are hacky and not very clean for distributing to arbitrary computing environments. If powershell were used instead batch cmd there is this method which looks like the best approach to me. I haven't exercised it yet to see where it might break down.

maphew commented 5 years ago

@BjornFJohansson I meant the terminal window flashing, not path.

newville commented 5 years ago

@maphew Thanks for those links -- I hadn't seen those.

It makes me wonder how far down this path we should really go. Like, this is not really about "creating the shortcut" but about what that shortcut path is. The user could use many methods (or really even including envrunner.bat) for building a VBS script or a batch file or whatever else around the command they really want to run.

To be clear, I'm not opposed to trying some of the approaches for the most common needs and we should definitely support "run in minimized window" on Windows.

I think that Powershell cannot be assumed to be installed on Windows 7, but that it might be fair to assume that on Windows 10 (and official support for Windows 7 is ending soon).

I don't have strong preferences on any of this.

BjornFJohansson commented 5 years ago

I think that my method above only relies on vbscript that has been around since windows 98 by default?

newville commented 5 years ago

@BjornFJohansson Yeah, I do think that running vbscript would be OK. What is less clear to me is whether we want to always include that as part of the shortcut-building process or whether we would rather instruct folks when and how to make such a small vbscript and then use pyshortcuts to build a shortcut to that.

That is, is this a problem to solve with code or with documentation? Honestly, I'm not sure.

I think the situation with envrunner.bat is similar: is this something that we should be handling as part of the shortcut building process?

BjornFJohansson commented 5 years ago

I think it all comes down to what most peoples use case is. I wanted something that behaves like a "normal" app without any command line window at all. I looked at the links (thanks @maphew) and I saw that the method I used was already documented there:

CreateObject(“Wscript.Shell”).Run “””” & WScript.Arguments(0) & “”””, 0, False

I put three vbscript launchers I made recently below for reference. wikidpad is an entry point created by setuptools. I suppose running the python script in "Scripts" would also work.

Set oShell = CreateObject("WScript.Shell")
oShell.Run "cmd /C C:\Users\cube\Anaconda3\Scripts\activate WIKIDPAD37 & wikidpad", false

Set oShell = CreateObject("WScript.Shell")
oShell.Run "cmd /C C:\Users\Tatiana\Anaconda3\Scripts\activate WIKIDPAD37 & C:\Users\Tatiana\Anaconda3\envs\WIKIDPAD37\Scripts\wikidpad.exe", false

The last one contains mods for dealing with spaces in the windows user folder name.

Set oShell = CreateObject("WScript.Shell")
oShell.Run "cmd /C C:\Users\""Paulo Silva""\Anaconda3\Scripts\activate WIKIDPAD37 & wikidpad", false

I also do not know if my use case is common enough to make it worthwhile to automate. I would probably prefer it, but then again the hard part for me was to figure out how to do it.

newville commented 5 years ago

@BjornFJohansson Right, I think the question is whether making a shortcut should always make a small batch file or VB script. That would imply that creating a Windows shortcut is not sufficient.

I could be OK with saying that and using the VB wrapper, but it does mean that we have to support it and make sure it is not worse than just making a plain shortcut. I guess the question is can we (I think that we = you, @maphew, and me) agree? The current code mostly works for me, but I see these warts on Windows too, and I'm not opposed to the VB-script approach.

Perhaps "use a VB rwrapper" and/or "use an Anaconda Environment wrapper" be Windows-only options to make_shortcut?

I don't have strong preferences here and am only slightly concerned about being able to support this code and approach.

BjornFJohansson commented 5 years ago

@newville What does the support situation look like right now? I have linux mint on my laptop and occasionally access to windows 10. What is the development system for pyshortcuts? Could the functionality be tested somehow using travis and appveyor?

newville commented 5 years ago

@BjornFJohansson Well, this is entirely on github ;). The project is 13 months old with ~170 commits. We have tests with Travis and Appveyor but they test only whether a shortcut can be created, but how it runs.

Since this issue is about adding features, I think it is fair to discuss when that feature (automatic VB wrapping) would be used and whether it should be optional or always used. For this particular issue, which is not exactly about the making of a shortcut but rather about the target command that shortcut points to, it may be that documenting how to make a VBscript one-liner is sufficient.

I have not seen any real advocating from you or anyone else about how this would be added to pyshortcuts. Should using a VBscript wrapper be a a) build option with an additional function / command-line argument. If so, default on/off? b) documented.

I guess we should also treat the use of envrunner.bat script the same way. Should that be left as is, replaced by documentation, or turned into a build option?

Really, I have no strong preference. Help on any aspect of this would be great. Should we set up a pyshortcuts organization?