I'm working on a Python console app.
I want to check if the focus is on the console of my application.
I can assume my code will be executed on a Windows PC.
At the moment I'm using this unsafe version:
import win32gui
# Before the execution starts, I assume the focus will be on the console
CURRENT_CONSOLE = win32gui.GetForegroundWindow()
...
# Check if the console has the focus
if win32gui.GetForegroundWindow() == CURRENT_CONSOLE:
...
The obvious problem is that the user can change the focus before the execution arrives to the row that defines CURRENT_CONSOLE.
There is another problem:
If I'm debugging Visual Code with the integrated console, my method cannot tell whether the focus is on the console or somewhere else in the Visual Code window (for example on the code).
Try this:
import win32gui,win32process,os
focus_window_pid = win32process.GetWindowThreadProcessId(win32gui.GetForegroundWindow())[1]
current_process_pid = os.getppid()
print(focus_window_pid == current_process_pid )
win32process.GetWindowThreadProcessId(win32gui.GetForegroundWindow())[1] will get the parent process pid, so we need to use os.getppid() to get the parent pid of python process.
But if you are using other method to run your python script(eg: vscode), this method may not work.
Related
I am learning the subprocess module in python, and to my understanding, the wait method, blocks the thread from executing the rest of the code until the launched process is closed. But when I cann the wait method it still executes the rest of the code:
def startCalc():
x = subprocess.Popen('C:\\Windows\\System32\\calc.exe')
time.sleep(5)
x.wait()
print('finished waiting')
print(x.poll())
print(x.wait())
startCalc()
If I am not wrong, the "finished waiting statement, would not appear in the output until I close the calculator, but it does.
Where am I wrong?
The problem isn't with your code, but rather with the calc.exe executable. It starts the calculator and returns immediately with 0 exit status. So, from the perspective of your program, the process ran to completion successfully. As far as I know, calc.exe doesn't have a way to launch in attached mode.
Test this by opening a powershell, or cmd terminal and launching calc.exe. You get the prompt back immediately.
I am not familiar with the ".wait" function, but if you want your code to wait for the execution of the "calc.exe" process, you could replace "Popen" with "call":
x = subprocess.call('C:\\Windows\\System32\\calc.exe')
I am starting with Python and want to use it to dispatch an application with win32com (the application is PTV Vissim, for traffic modelling), however, after the script is done with whatever I ask it to do, it closes and kills Vissim with it too.
Is there a way to avoid this?
i.e. I want the Python script to finish but leaving the dispatched application open for the user to keep working with it.
This is the code I'm using:
import win32com.client as com
import os
# Opening a new Vissim window
Vissim = com.Dispatch("Vissim.Vissim")
# Define filename and save as new model
Path = "C:\ModelWIP\Vissim\Script_test"
Filename = os.path.join(Path, "My_Model.inpx")
Vissim.SaveNetAs(Filename)
# Keeps python command line open until the user confirms
raw_input('Press any key to exit')
The final bit with raw_input is there to keep the script from finishing and therefore keeping the Vissim instance alive, this is the only solution I've found so far.
Can you open Vissim with the os.system command? If you can, it will let you terminate the Python process and keep the Vissim instance opened.
E.g.:
os.system("start vissim.exe")
I am launching a series of subprocess one after the other, something like
for variables in my_list:
proc = subprocess.Popen(**variables)
proc.wait()
however if one of them crashes Windows pops up a window saying that the program has stopped working; since the process hasn't been killed yet, the program waits until I click the "close program" button
I'm wondering if there is a way to tell Python to open this process without UI or make it so that if it crashes it doesn't pop up error reports. The documentation doesn't seem to address any of this.
I'm using python 2.7, so I can't make use of the timeout flag that is present in python 3.
The error mode is inherited by child processes. Set it via ctypes. For example:
import ctypes
kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
SEM_FAILCRITICALERRORS = 1
SEM_NOGPFAULTERRORBOX = 2
prev_error_mode = kernel32.SetErrorMode(SEM_FAILCRITICALERRORS |
SEM_NOGPFAULTERRORBOX)
So I have a program which are working in PyCharm for a long time and sometimes it crashes. And after it I get some logs in its console. However it isn't convenient to check it every 10 minutes, so is it possible to get some notifications on my display outside PyCharm when my program has crashed? Maybe some sound or pop-up window or somthing else...
You can use the \a character to make an "ASCII Bell", which can either make an alert sound or be reconfigured by the OS to make a visual notification.
import atexit
#atexit.register
def notify():
# Python 2: print "\a"
# or from __future__ import print_function
# at the top of your code
print("\a")
# Let's crash
1/0
Note that with atexit, the notify function won't run when exiting to interactive mode (the -i flag when starting Python). It will though, when you exit with exit()/quit(), Ctrl-Z, or Ctrl-C, an exception, or reaching the end of code.
I am working on a text based game that I run by double clicking on my top level script namely TopLevel.py.
I am looking for a way to open two terminals in this script. In the one terminal the main game will be run where damage is done and spells are used etc. In the other terminal I would like to display a list of commands that the user can type in , and I want the latter one to stay there and not close until the game is finished. I am not going to show you the whole top level script (it is too long) but this is basically what I want to achieve:
def displayCommands(hero):
list_of_commands = []
#this contains all my commands that the user can type in
def main():
hero = Hero() #make hero instance
enemy = Enemy() #make and enemy instance
a_game = TopLevel(hero,enemy) #create game engine
a_game.play() #start game
#implement code here to open another terminal
#and display user commands in there
Is there a way that I can open another terminal in this script and pass the displayCommands() function as a parameter to display its contents in the second terminal? Any help will be appreciated :)
It's possible for one Python script to spawn another that will run in parallel with it via subprocess. The spawned process can then display any text piped to it (via normal print statements or calls) in a simple tkinter-based window -- see the errorwindow module in this answer of mine for more information.
It likely doesn't matter how the original script gets started. I personally have used it both in ones that were started from a command shell as well as from other tkinter based applications -- so starting yours from powershell should be fine. The module's original author was using Linux or something similar, I believe.
You should convert your second program to .exe first,the one will display user commands. Say you saved it as usercommands.exe, after then in your main script use this to open that;
import subprocess
subprocess.Popen([r"usercommands.exe"],
creationflags=subprocess.CREATE_NEW_CONSOLE)
It'll open another console window that runs usercommands.exe when you run your main file.
Notes;
They must be in the same directory, your main file and .exe file
usercommands.exe must show the commands in an infinite loop(while True), so it's
going to display commands untill the user close it.
Edit;
Now, we have some spells and usercommands will have to use that spell variables after then show us some combinations. For doing this, we have to import your first file to usercommands script.It's going to like this;
usercommands.py
import mainfile #mainfile.py
if choose == mainfile.wizard:
print (something)
if choose == mainfile.subzero:
print (something)
The algorithm should be like this,you will convert usercommands.py to .exe then it will work as you want I guess, we can't now before you try it ;)