How do you "launch" a Windows protocol from Python? - python-3.x

We have a python script that needs to trigger the open of the Microsoft Store. We believe that the easiest way to do that is to use the ms-windows-store:// protocol.
We're currently doing that like this
import subprocess
ret = subprocess.call(["start", "ms-windows-store://pdp/?ProductId=9WZDNCRFHVJL"], shell=True)
Is that the recommended way to do this? I'm not sure if using start is correct here, or if there's something better?

Use os.startfile("ms-windows-store://pdp/?ProductId=9WZDNCRFHVJL"). This calls WINAPI ShellExecuteW directly. If you use subprocess, you have the expense of starting a child process. Plus CMD's start command will first search PATH to find a file that it can execute. Presuming nothing is found (and nothing likely will be, given this name), it hands the request off to ShellExecuteExW to let the OS shell handle it.

Related

Ubuntu: Python3 check if file exists with subprocess

I managed to install windows based network printer with python3 on ubuntu.
For better coding, I want to check first if the file with the drivers in it exists after the download. I know it is possible with os.path.isfile or something like that but I would like to do that with subprocess although os will not be supported in the future anymore.
So how do I do it? With subprocess.call or something like that?
to check for a file to be present, You ideally use pathlib, which is the pythonic and portable way to interact with the filesystem.
But to avoid Time of Check to Time of Use Errors (TOCTTOU) You should consider:
Instead of :
if check_printer_present():
# now, after checking the printer is present,
# the printer might go offline
use_printer()
better use:
try:
use_printer()
except PrinterError():
printer_error_cleanup()
see:
https://de.wikipedia.org/wiki/Time-of-Check-to-Time-of-Use-Problem
You might remember that idiom as :
it's better to ask forgiveness than permission
(t is better to act decisively and apologize for it later
than to seek approval to act and risk delay, objections, etc.)

How to, in Python, ignore certain/all keypresses while function executing in program on Macintosh

I would like to know, how would I, in Python, be able to ignore certain/all keypresses by the user while a certain function in the program is executing? Cross platform solutions are preferred, but if that is not possible, then I need to know how to do this on Macintosh. Any help is greatly appreciated! :)
EDIT: Right now, I am processing keypresses through the turtle module's onkey() function since I did create a program using turtle. I hope this helps avoid any confusion, and again, any help is greatly appreciated! :)
You might want to modify your question to show how you're currently processing key-presses. For example is this a command-line program and you're using curses?
You could use os.uname to return the os information or sys.platform, if that isn't available. The Python documentation for sys.platform indicates that 'darwin' is returned for OSX apple machines.
If the platform is darwin then you could, in your code, ignore whatever key-presses you want to.
Edit (Update due to changed question):
If you want to ignore key-presses when a certain function is being called you could either use a lock to stop the key-press function call and your particular function being executed together.
Here is an example of using a lock, this may not run, but it should give you a rough idea of what's required.
import _thread
a_lock = _thread.allocate_lock()
def certainFunction():
with a_lock:
print("Here's the code that you don't want to execute at the same time as onSpecificKeyCall()")
def onSpecificKeyCall():
with a_lock:
print("Here's the code that you don't want to execute at the same time as certainFunction()")
Or, depending on the circumstances, when the function which you don't want interrupting with a key press is called, you could call onkey() again, with the specific key to ignore, to call to a function that doesn't do anything. When your particular function has finished, you could call onkey() again to bind the key press to the function that processes the input.
I found similar problems, maybe it will help you with your problem:
globally capture, ignore and send keyevents with python xlib, recognize fake input
How do I 'lock the keyboard' to prevent any more keypresses being sent on X11/Linux/Gnome?
https://askubuntu.com/questions/160522/python-gtk-event-ignore

Can I alter Python source code while executing?

What I mean by this is:
I have a program. The end user is currently using it. I submit a new piece of source code and expect it to run as if it were always there?
I can't find an answer that specifically answers the point.
I'd like to be able to say, "extend" or add new features (rather than fix something that's already there on the fly) to the program without requiring a termination of the program (eg. Restart or exit).
Yes, you can definitely do that in python.
Although, it opens a security hole, so be very careful.
You can easily do this by setting up a "loader" class that can collect the source code you want it to use and then call the exec builtin function, just pass some python source code in and it will be evaluated.
Check the package
http://opensourcehacker.com/2011/11/08/sauna-reload-the-most-awesomely-named-python-package-ever/ . It allows to overcome certain raw edges of plain exec. Also it may be worth to check Dynamically reload a class definition in Python

Application to accept arguments while running

I am using visual studio 2008 and MFC. I accept arguments using a subclass of CCommandLineInfo and overriding ParseParam().
Now I want to pass these arguments to the application while running. For example "test.exe /start" and then to type in the console "test.exe /initialize" to be initialized again.
is there any way to do that?
Edit 1: Some clarifications. My program starts with "test.exe /start". I want to type "test.exe /initialize" and initialize the one and only running process (without closing/opening). And by initialize I mean to read a different XML file, to change some values of the interface and other things.
I cannot think of an easy way to accomplish what you're asking about.
However, you could develop your application to specifically receive commands, and given those commands take any actions you wanted based upon receiving them. Since you're already using MFC, you can do this rather easily. Create a Window (HWND) for your application and register it. It doesn't have to be visible (this won't necessarily make you application a GUI application). Implement a WndProc, and define specific messages that you will receive based on WM_USER + <xxx>.
First and obvious question is why you want to have threads, instead of processes.
You may use GetCommandLine and CommandLineToArgvW to get the fully formatted command line. Detect the arguments, and the call CreateProcess or ShellExecute passing /watever to spawn the process. You may also want to use GetModuleBaseName to get the name of your own EXE.

Catching a direct redirect to /dev/tty

I'm working on an application controller for a program that is spitting text directly to /dev/tty.
This is a production application controller that must be able to catch all text going to the terminal. Generally, this isn't a problem. We simply redirect stdout and stderr. This particular application is making direct calls to echo and redirecting the result to /dev/tty (echo "some text" > /dev/tty). Redirects via my application controller are failing to catch the text.
I do have the source for this application, but am not in a position to modify it, nor is it being maintained anymore. Any ideas on how to catch and/or throw away the output?
screen -D -m yourEvilProgram
should work. Much time passed sinced I used it, but if you need to read some of its output it could even be possible that you could utilize some sockets to read it.
[Added: two links, Rackaid and Pixelbeat, and the home page at GNU]
The classic solution to controlling an application like this is Expect, which sets up pseudo-terminals, does logging, and drives the controlled application from a script. It comes with lots of sample scripts so you can probably just adapt one to fit your needs.
This is what I did in python
import pty, os
pid, fd = pty.fork()
if pid == 0: # In the child process execute another command
os.execv('./my-progr', [''])
print "Execv never returns :-)"
else:
while True:
try:
print os.read(fd,65536),
except OSError:
break
I can't quite determine whether the screen program mentioned by #flolo will do what you need or not. It may, but I'm not sure whether there is a logging facility built in, which appears to be what you need.
There probably is a program out there already to do what you need. I'd nominate sudosh as a possibility.
If you end up needing to write your own, you'll probably need to use a pseudo-tty (pty) and have your application controller sit in between the user's real terminal connection and the the pty device, where it can log whatever you need it to log. That's not trivial. You can find information about this in Rochkind's "Advanced UNIX Programming, 2nd Edn" book, and no doubt other similar books (Stevens' "Advanced Programming in the UNIX Environment" book is a likely candidate, but I don't have a copy to verify that).

Resources