How to Close a program using python? - python

Is there a way that python can close a windows application (example: Firefox) ?
I know how to start an app, but now I need to know how to close one.

# I have used subprocess comands for a while
# this program will try to close a firefox window every ten secounds
import subprocess
import time
# creating a forever loop
while 1 :
subprocess.call("TASKKILL /F /IM firefox.exe", shell=True)
time.sleep(10)

If you're using Popen, you should be able to terminate the app using either send_signal(SIGTERM) or terminate().
See docs here.

in windows you could use taskkill within subprocess.call:
subprocess.call(["taskkill","/F","/IM","firefox.exe"])
/F forces process termination. Omitting it only asks firefox to close, which can work if the app is responsive.
Cleaner/more portable solution with psutil (well, for Linux you have to drop the .exe part or use .startwith("firefox"):
import psutil,os
for pid in (process.pid for process in psutil.process_iter() if process.name()=="firefox.exe"):
os.kill(pid)
that will kill all processes named firefox.exe
By the way os.kill(pid) is "overkill" (no pun intended). process has a kill() method, so:
for process in (process for process in psutil.process_iter() if process.name()=="firefox.exe"):
process.kill()

You want probably use os.kill http://docs.python.org/library/os.html#os.kill

In order to kill a python tk window named MyappWindow under MS Windows:
from os import system
system('taskkill /F /FI "WINDOWTITLE eq MyappWindow" ')
stars maybe used as wildcard:
from os import system
system('taskkill /F /FI "WINDOWTITLE eq MyappWind*" ')
Please, refer to "taskkill /?" for additional options.

On OS X:
Create a shell script and put:
killall Application
Replace Application with a running app of your choice.
In the same directory as this shell script, make a python file.
In the python file, put these two lines of code:
from subprocess import Popen
Popen('sh shell.sh', shell=True)
Replace shell.sh with the name of your created shell script.

An app(a running process) can be closed by it's name using it's PID(Process ID) and by using psutil module. Install it in cmd using the command:
pip install psutil
After installing, run the code given below in any .py file:
import psutil
def close_app(app_name):
running_apps=psutil.process_iter(['pid','name']) #returns names of running processes
found=False
for app in running_apps:
sys_app=app.info.get('name').split('.')[0].lower()
if sys_app in app_name.split() or app_name in sys_app:
pid=app.info.get('pid') #returns PID of the given app if found running
try: #deleting the app if asked app is running.(It raises error for some windows apps)
app_pid = psutil.Process(pid)
app_pid.terminate()
found=True
except: pass
else: pass
if not found:
print(app_name+" not found running")
else:
print(app_name+'('+sys_app+')'+' closed')
close_app('chrome')
After running the code above you may see the following output if google chrome was running:
>>> chrome(xyz) closed
Feel free to comment in case of any error

Related

How to stop a python program that is running in the background shell [duplicate]

I've got a long running python script that I want to be able to end from another python script. Ideally what I'm looking for is some way of setting a process ID to the first script and being able to see if it is running or not via that ID from the second. Additionally, I'd like to be able to terminate that long running process.
Any cool shortcuts exist to make this happen?
Also, I'm working in a Windows environment.
I just recently found an alternative answer here: Check to see if python script is running
You could get your own PID (Process Identifier) through
import os
os.getpid()
and to kill a process in Unix
import os, signal
os.kill(5383, signal.SIGKILL)
to kill in Windows use
import subprocess as s
def killProcess(pid):
s.Popen('taskkill /F /PID {0}'.format(pid), shell=True)
You can send the PID to the other programm or you could search in the process-list to find the name of the other script and kill it with the above script.
I hope that helps you.
You're looking for the subprocess module.
import subprocess as sp
extProc = sp.Popen(['python','myPyScript.py']) # runs myPyScript.py
status = sp.Popen.poll(extProc) # status should be 'None'
sp.Popen.terminate(extProc) # closes the process
status = sp.Popen.poll(extProc) # status should now be something other than 'None' ('1' in my testing)
subprocess.Popen starts the external python script, equivalent to typing 'python myPyScript.py' in a console or terminal.
The status from subprocess.Popen.poll(extProc) will be 'None' if the process is still running, and (for me) 1 if it has been closed from within this script. Not sure about what the status is if it has been closed another way.
This worked for me under windows 11 and PyQt5:
subprocess.Popen('python3 MySecondApp.py')
Popen.terminate(app)
where app is MyFirstApp.py (the caller script, running) and MySecondApp.py (the called script)

Terminate a gnome-terminal opened with subprocess

Using subprocess and the command 'gnome-terminal -e bash' I can open up a gnome-terminal as desired (and have it stick around). This is done with either
p=subprocess.Popen(['gnome-terminal', '-e', 'bash'])
or
p=subprocess.Popen(['gnome-terminal -e bash'], shell=True)
but I cannot close the terminal using p.terminate() or p.kill(). From what I understand, this is a little trickier when using shell=True but I did not expect to run into problems otherwise.
To terminate a terminal and its children (in the same process group):
#!/usr/bin/env python
import os
import signal
import subprocess
p = subprocess.Popen(['gnome-terminal', '--disable-factory', '-e', 'bash'],
preexec_fn=os.setpgrp)
# do something here...
os.killpg(p.pid, signal.SIGINT)
--disable-factory is used to avoid re-using an active terminal so that we can kill newly created terminal via the subprocess handle
os.setpgrp puts gnome-terminal in its own process group so that os.killpg() could be used to send signal to this group
You should be able to do this workaround:
get the process id
kill the process
Working Solution: Close gnome-terminal-server
As suggested by #j-f-sebastian in the comment, gnome-terminal
just sends the request (to gnome-terminal-server) to start a new terminal and exits immediately -- there is nothing to kill the process is already dead (and newly created processes are not descendants:  the new bash process is a child of gnome-terminal-server, not gnome-terminal).
import subprocess
import os, signal
import time
p=subprocess.Popen(['gnome-terminal -e bash'], stdout=subprocess.PIPE, shell=True, preexec_fn=os.setsid)
print "this is going to be closed in 3 sec"
time.sleep(3)
# this line returns the list of bash instances pid as string
bash_pids = subprocess.check_output(["pidof", "bash"])
# I get the last instance opened
pid_to_kill = bash_pids.split(" ")[0]
os.kill(int(pid_to_kill), signal.SIGTERM)
My solution is following this logic:
run gnome-terminal
get the latest bash instance opened process id
kill this process id
Broken solutions
These solutions might work in simpler cases:
Solution 1
import subprocess
import os, signal
p=subprocess.Popen(['gnome-terminal -e bash'], shell=True)
p_pid = p.pid # get the process id
os.kill(p_pid, signal.SIGKILL)
In order to choose the appropriate method of signal to pass instead of SIGKILL you can refer the signal documentation. E.g.
On Windows, signal() can only be called with SIGABRT, SIGFPE, SIGILL, SIGINT, SIGSEGV, or SIGTERM
For Unix you have a quite extensive list of method to call.
To have a better overview about os.kill, you can refer its documentation.
Solution 2
An alternative method useful for Unix could be:
import subprocess
import os, signal
p=subprocess.Popen(['gnome-terminal -e bash'], stdout=subprocess.PIPE, shell=True, preexec_fn=os.setsid)
os.killpg(os.getpgid(p.pid), signal.SIGTERM)
It seems that your process is opening child process that prevent the parent to be close. Adding a session id to your parent process, you should be able to fix it.
Solution 3
import subprocess, psutil
def kill(p_pid):
process = psutil.Process(p_pid)
for proc in process.get_children(recursive=True):
proc.kill()
process.kill()
p = subprocess.Popen(['gnome-terminal -e bash'], shell=True)
try:
p.wait(timeout=3)
except subprocess.TimeoutExpired:
kill(p.pid)
This solution requires psutil.
Solution 4
According to askubuntu, it seems that the best way to close a gnome terminal instance would be to execute a bash command like:
killall -s {signal} gnome-terminal
where {signal} simulates Alt + F4.
You can try to do it using [pexpect]:
p = pexpect.spawn(your_cmd_here)
p.send('^F4')
I wanted to add this snippet for anyone who is running on Linux Ubuntu and trying to open a subprocess, run a script, and terminate it after a time.wait().
I found a litany of solutions that would open a window, but not close it. Or a solution would open a window, and close it, but wouldn't run the script inside the terminal.
There was no exact answer so I had to hack together several solutions, as I am a novice when it comes t subprocess/shell.
This snippet was able to open a subprocess, run the script, and when 10 seconds had passed the subprocess was terminated. Again, this was built ofn the shoulders of giants. I hope this saves someone time; cheers.
import os
import signal
import subprocess
import time
command = 'python3 Rmonitor.py'
p = subprocess.Popen(['gnome-terminal','--disable-factory', '--', 'bash', '-c', command],preexec_fn=os.setpgrp)
time.sleep(10)
os.killpg(p.pid, signal.SIGINT)

How to shutdown a computer using Python

I've written a Python script which should eventually shutdown the computer.
This line is a part of it :
os.system("shutdown /p")
It makes some sort of a shutdown but remains on the turn-on Windows control pannel (where the user can switch the computer users).
Is there a way to fully shutdown the computer?
I've tried other os.system("shutdown ___") methods with no success.
Is there another method which might help?
import os
os.system('shutdown -s')
This will work for you.
For Linux:
import os
os.system('sudo shutdown now')
or: if you want immediate shutdown without sudo prompt for password, use the following for Ubuntu and similar distro's:
os.system('systemctl poweroff')
Using ctypes you could use the ExitWindowsEx function to shutdown the computer.
Description from MSDN:
Logs off the interactive user, shuts down the system, or shuts down and restarts the system.
First some code:
import ctypes
user32 = ctypes.WinDLL('user32')
user32.ExitWindowsEx(0x00000008, 0x00000000)
Now the explanation line by line:
Get the ctypes library
The ExitWindowsEx is provided by the user32.dll and needs to be loaded via WinDLL()
Call the ExitWindowsEx() function and pass the necessary parameters.
Parameters:
All the arguments are hexadecimals.
The first argument I selected:
shuts down the system and turns off the power. The system must support the power-off feature.
There are many other possible functions see the documentation for a complete list.
The second argument:
The second argument must give a reason for the shutdown, which is logged by the system. In this case I set it for Other issue but there are many to choose from. See this for a complete list.
Making it cross platform:
This can be combined with other methods to make it cross platform. For example:
import sys
if sys.platform == 'win32':
import ctypes
user32 = ctypes.WinDLL('user32')
user32.ExitWindowsEx(0x00000008, 0x00000000)
else:
import os
os.system('sudo shutdown now')
This is a Windows dependant function (although Linux/Mac will have an equivalent), but is a better solution than calling os.system() since a batch script called shutdown.bat will not conflict with the command (and causing a security hazard in the meantime).
In addition it does not bother users with a message saying "You are about to be signed out in less than a minute" like shutdown -s does, but executes silently.
As a side note use subprocess over os.system() (see Difference between subprocess.Popen and os.system)
As a side note: I built WinUtils (Windows only) which simplifies this a bit, however it should be faster (and does not require Ctypes) since it is built in C.
Example:
import WinUtils
WinUtils.Shutdown(WinUtils.SHTDN_REASON_MINOR_OTHER)
The only variant that really workes for me without any problem is:
import os
os.system('shutdown /p /f')
Python doc recommends using subprocess instead of os.system. It intends to replace old modules like os.system and others.
So, use this:
import subprocess
subprocess.run(["shutdown", "-s"])
And for linux users -s is not required, they can just use
import subprocess
subprocess.run(["shutdown"])
Try this code snippet:
import os
shutdown = input("Do you wish to shutdown your computer ? (yes / no): ")
if shutdown == 'no':
exit()
else:
os.system("shutdown /s /t 1")
This Python code may do the deed:
import os
os.system('sudo shutdown -h now')
Here's a sample to power off Windows:
import os
os.system("shutdown /s /t 1")
Here's a sample to power off Linux (by root permission):
import os
os.system("shutdown now -h")
As you wish, winapi can be used.
import win32api,win32security,winnt
win32security.AdjustTokenPrivilege(win32security.OpenProcessHandle(win32api.GetCurrentProcess(),win32security.ADJUST_TOKEN_PRIVILEGE | win32security.TOKEN_QUERY),False,[(win32security.LookupPrivilegeValue(None,winnt.SE_SHUTDOWN_NAME),winnt.SE_PRIVILEGE_ENABLE)])
win32api.InitateSystemShutdown(None,"Text",second,Force_Terminate_Apps_as_boolean,Restart_as_boolean)
pip install schedule
In case you also want to schedule it:
import schedule
import time
import os
when= "20:11"
print("The computer will be shutdown at " + when + "")
def job():
os.system("shutdown /s /t 1")
schedule.every().day.at(when).do(job)
while True:
schedule.run_pending()
time.sleep(1)

Python script running in one system will perform the result in another system

I am trying to write a python script which when executes will open a Maya file in another computer and creates its playblast there. Is this possible? Also I would like to add one more thing that the systems I use are all Windows. Thanks
Yes it is possible, i do this all the time on several computers. First you need to access the computer. This has been answered. Then call maya from within your shell as follows:
maya -command myblast -file filetoblast.ma
you will need myblast.mel somewhere in your script path
myblast.mel:
global proc myblast(){
playblast -widthHeight 1920 1080 -percent 100
-fmt "movie" -v 0 -f (`file -q -sn`+".avi");
evalDeferred("quit -f");
}
Configure what you need in this file such as shading options etc. Please note calling Maya GUI uses up one license and playblast need that GUI (you could shave some seconds by not doing the default GUI)
In order to execute something on a remote computer, you've got to have some sort of service running there.
If it is a linux machine, you can simply connect via ssh and run the commands. In python you can do that using paramiko:
import paramiko
ssh = paramiko.SSHClient()
ssh.connect('127.0.0.1', username='foo', password='bar')
stdin, stdout, stderr = ssh.exec_command("echo hello")
Otherwise, you can use a python service, but you'll have to run it beforehand.
You can use Celery as previously mentioned, or ZeroMQ, or more simply use RPyC:
Simply run the rpyc_classic.py script on the target machine, and then you can run python on it:
conn = rpyc.classic.connect("my_remote_server")
conn.modules.os.system('echo foo')
Alternatively, you can create a custom RPyC service (see documentation).
A final option is using an HTTP server like previously suggested. This may be easiest if you don't want to start installing everything. You can use Bottle which is a simple HTTP framework in python:
Server-side:
from bottle import route, run
#route('/run_maya')
def index(name):
# Do whatever
return 'kay'
run(host='localhost', port=8080)
Client-side:
import requests
requests.get('http://remote_server/run_maya')
One last option for cheap rpc is to run maya.standalone from a a maya python ("mayapy", usually installed next to the maya binary). The standalone is going to be running inside a regular python script so it can uses any of the remote procedure tricks in KimiNewts answer.
You can also create your own mini-server using basic python. The server could use the maya command port, or a wsgi server using the built in wsgiref module. Here is an example which uses wsgiref running inside a standalone to control a maya remotely via http.
We've been dealing with the same issue at work. We're using Celery as the task manager and have code like this inside of the Celery task for playblasting on the worker machines. This is done on Windows and uses Python.
import os
import subprocess
import tempfile
import textwrap
MAYA_EXE = r"C:\Program Files\Autodesk\Maya2016\bin\maya.exe"
def function_name():
# the python code you want to execute in Maya
pycmd = textwrap.dedent('''
import pymel.core as pm
# Your code here to load your scene and playblast
# new scene to remove quicktimeShim which sometimes fails to quit
# with Maya and prevents the subprocess from exiting
pm.newFile(force=True)
# wait a second to make sure quicktimeShim is gone
time.sleep(1)
pm.evalDeferred("pm.mel.quit('-f')")
''')
# write the code into a temporary file
tempscript = tempfile.NamedTemporaryFile(delete=False, dir=temp_dir)
tempscript.write(pycmd)
tempscript.close()
# build a subprocess command
melcmd = 'python "execfile(\'%s\')";' % tempscript.name.replace('\\', '/')
cmd = [MAYA_EXE, '-command', melcmd]
# launch the subprocess
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
proc.wait()
# when the process is done, remove the temporary script
try:
os.remove(tempscript.name)
except WindowsError:
pass

Is it possible to kill a process on Windows from within Python?

I'm using Python 2.6. Sometimes there become several instances of a certain process open, and that process causes some problems in itself. I want to be able to programatically detect that there are multiple instances of that process and to kill them.
For example, maybe in some cases there are 50 instances of make.exe open. I want to be able to tell that there are 20 instances open, and to kill them all. How is this accomplished?
I would think you could just use taskkill and the Python os.system()
import os
os.system("taskkill /im make.exe")
Note: I would just note you might have to fully qualify the taskkill path. I am using a Linux box so I can't test...
Yes,You can do it
import os
os.system("taskkill /f /im Your_Process_Name.exe")
/f : Specifies that process(es) be forcefully terminated.
/im (ImageName ): Specifies the image name of the process to be
terminated.
For more info regarding TaskKill
There is a nice cross-platform python utility psutil that exposes a kill() routine on a processes that can be listed with psutil.process_iter().
There is already an example in the other thread: https://stackoverflow.com/a/4230226/4571444
You can use the TerminateProcess of the win32 api to kill a process. See the following example : http://code.activestate.com/recipes/347462-terminating-a-subprocess-on-windows/
You need to give it a process handle. If the process is started from your code, the process handle is returned by the CreateProcess or popen.
If the process was started by something else, you need to get this handle you can use EnumProcess or WMI to retrieve it.
How about this, I tested it with ActiveState Python 2.7:
import sys, traceback, os
def pkill (process_name):
try:
killed = os.system('tskill ' + process_name)
except Exception, e:
killed = 0
return killed
call it with:
pkill("program_name")
I think the code is like this will work:
import os
def terminate(ProcessName):
os.system('taskkill /IM "' + ProcessName + '" /F')
terminate('chrome.exe')

Categories

Resources