Send a signal/event to an independent process
So I have a completely independent process, with a known PID.
I want to send it some kind of interrupt from another unrelated process that will cause it to 'gracefully' exit.
In linux it would look something like this :
first_script:
def signal_handler(signum, stack):
print("SIGNAL RECIEVED")
sys.exit()
signal.signal(signal.SIGUSR1, handle_signal)
while True:
print("Im working")
Second script:
known_pid = input("Enter pid")
os.kill(int(known_pid), signal.SIGUSR1)
Since, Windows doesn't support signaling in this way, it obviously won't work but I couldn't find any other simple solution (After quite extensive research).
python python-3.x windows
add a comment |
So I have a completely independent process, with a known PID.
I want to send it some kind of interrupt from another unrelated process that will cause it to 'gracefully' exit.
In linux it would look something like this :
first_script:
def signal_handler(signum, stack):
print("SIGNAL RECIEVED")
sys.exit()
signal.signal(signal.SIGUSR1, handle_signal)
while True:
print("Im working")
Second script:
known_pid = input("Enter pid")
os.kill(int(known_pid), signal.SIGUSR1)
Since, Windows doesn't support signaling in this way, it obviously won't work but I couldn't find any other simple solution (After quite extensive research).
python python-3.x windows
Does the process have a window that can be sentWM_CLOSE
? Most GUI apps will exit gracefully (including asking to save files) if the main window is closed. This is what taskkill.exe does by default without the /F option. This can also be used for a console process if it's the effective owner of the console window (usually if it allocated the console). When the console window is closed, all applications attached to it (not just the owner) have no more than 5 seconds to handle the control event and exit gracefully before getting terminated.
– eryksun
Nov 13 '18 at 18:14
@eryksun It isnt a windows application(no GUI), and it isnt the owner of the console (otherwise I could use some varation of ctrl+c signals).
– Rohi
Nov 14 '18 at 7:02
Even if it were a console app, sending Ctrl+C is not simple in Windows. You have to be attached to the console (e.g.AttachConsole
,FreeConsole
).GenerateConsoleCtrlEvent
works only with process groups, not arbitrary process IDs. If you know the group ID (i.e. the PID of the lead process), then you probably created the process withCREATE_NEW_PROCESS_GROUP
, which disables Ctrl+C by default, so you have to use Ctrl+Break instead. Otherwise without a known group, you have to send to group 0 (all attached processes) and ignore the event in your own process.
– eryksun
Nov 14 '18 at 12:18
If it has no window or console, your last hope is that it's hosting a service (or services) that you can stop. Otherwise there's no standard way to signal a process. Windows has capabilities for this such as asynchronous procedure calls (APCs), named pipes, mailslots, events, and semaphores, but they're not a generic mechanism. An application has to be designed with a documented way to receive the signal.
– eryksun
Nov 14 '18 at 12:28
@Rohi does any of the answers have what you need? If not, what is missing? If you found a solution by yourself, please post it as an answer.
– roeen30
Nov 17 '18 at 17:53
add a comment |
So I have a completely independent process, with a known PID.
I want to send it some kind of interrupt from another unrelated process that will cause it to 'gracefully' exit.
In linux it would look something like this :
first_script:
def signal_handler(signum, stack):
print("SIGNAL RECIEVED")
sys.exit()
signal.signal(signal.SIGUSR1, handle_signal)
while True:
print("Im working")
Second script:
known_pid = input("Enter pid")
os.kill(int(known_pid), signal.SIGUSR1)
Since, Windows doesn't support signaling in this way, it obviously won't work but I couldn't find any other simple solution (After quite extensive research).
python python-3.x windows
So I have a completely independent process, with a known PID.
I want to send it some kind of interrupt from another unrelated process that will cause it to 'gracefully' exit.
In linux it would look something like this :
first_script:
def signal_handler(signum, stack):
print("SIGNAL RECIEVED")
sys.exit()
signal.signal(signal.SIGUSR1, handle_signal)
while True:
print("Im working")
Second script:
known_pid = input("Enter pid")
os.kill(int(known_pid), signal.SIGUSR1)
Since, Windows doesn't support signaling in this way, it obviously won't work but I couldn't find any other simple solution (After quite extensive research).
python python-3.x windows
python python-3.x windows
edited Nov 13 '18 at 15:30
Rohi
asked Nov 13 '18 at 14:05
RohiRohi
6441422
6441422
Does the process have a window that can be sentWM_CLOSE
? Most GUI apps will exit gracefully (including asking to save files) if the main window is closed. This is what taskkill.exe does by default without the /F option. This can also be used for a console process if it's the effective owner of the console window (usually if it allocated the console). When the console window is closed, all applications attached to it (not just the owner) have no more than 5 seconds to handle the control event and exit gracefully before getting terminated.
– eryksun
Nov 13 '18 at 18:14
@eryksun It isnt a windows application(no GUI), and it isnt the owner of the console (otherwise I could use some varation of ctrl+c signals).
– Rohi
Nov 14 '18 at 7:02
Even if it were a console app, sending Ctrl+C is not simple in Windows. You have to be attached to the console (e.g.AttachConsole
,FreeConsole
).GenerateConsoleCtrlEvent
works only with process groups, not arbitrary process IDs. If you know the group ID (i.e. the PID of the lead process), then you probably created the process withCREATE_NEW_PROCESS_GROUP
, which disables Ctrl+C by default, so you have to use Ctrl+Break instead. Otherwise without a known group, you have to send to group 0 (all attached processes) and ignore the event in your own process.
– eryksun
Nov 14 '18 at 12:18
If it has no window or console, your last hope is that it's hosting a service (or services) that you can stop. Otherwise there's no standard way to signal a process. Windows has capabilities for this such as asynchronous procedure calls (APCs), named pipes, mailslots, events, and semaphores, but they're not a generic mechanism. An application has to be designed with a documented way to receive the signal.
– eryksun
Nov 14 '18 at 12:28
@Rohi does any of the answers have what you need? If not, what is missing? If you found a solution by yourself, please post it as an answer.
– roeen30
Nov 17 '18 at 17:53
add a comment |
Does the process have a window that can be sentWM_CLOSE
? Most GUI apps will exit gracefully (including asking to save files) if the main window is closed. This is what taskkill.exe does by default without the /F option. This can also be used for a console process if it's the effective owner of the console window (usually if it allocated the console). When the console window is closed, all applications attached to it (not just the owner) have no more than 5 seconds to handle the control event and exit gracefully before getting terminated.
– eryksun
Nov 13 '18 at 18:14
@eryksun It isnt a windows application(no GUI), and it isnt the owner of the console (otherwise I could use some varation of ctrl+c signals).
– Rohi
Nov 14 '18 at 7:02
Even if it were a console app, sending Ctrl+C is not simple in Windows. You have to be attached to the console (e.g.AttachConsole
,FreeConsole
).GenerateConsoleCtrlEvent
works only with process groups, not arbitrary process IDs. If you know the group ID (i.e. the PID of the lead process), then you probably created the process withCREATE_NEW_PROCESS_GROUP
, which disables Ctrl+C by default, so you have to use Ctrl+Break instead. Otherwise without a known group, you have to send to group 0 (all attached processes) and ignore the event in your own process.
– eryksun
Nov 14 '18 at 12:18
If it has no window or console, your last hope is that it's hosting a service (or services) that you can stop. Otherwise there's no standard way to signal a process. Windows has capabilities for this such as asynchronous procedure calls (APCs), named pipes, mailslots, events, and semaphores, but they're not a generic mechanism. An application has to be designed with a documented way to receive the signal.
– eryksun
Nov 14 '18 at 12:28
@Rohi does any of the answers have what you need? If not, what is missing? If you found a solution by yourself, please post it as an answer.
– roeen30
Nov 17 '18 at 17:53
Does the process have a window that can be sent
WM_CLOSE
? Most GUI apps will exit gracefully (including asking to save files) if the main window is closed. This is what taskkill.exe does by default without the /F option. This can also be used for a console process if it's the effective owner of the console window (usually if it allocated the console). When the console window is closed, all applications attached to it (not just the owner) have no more than 5 seconds to handle the control event and exit gracefully before getting terminated.– eryksun
Nov 13 '18 at 18:14
Does the process have a window that can be sent
WM_CLOSE
? Most GUI apps will exit gracefully (including asking to save files) if the main window is closed. This is what taskkill.exe does by default without the /F option. This can also be used for a console process if it's the effective owner of the console window (usually if it allocated the console). When the console window is closed, all applications attached to it (not just the owner) have no more than 5 seconds to handle the control event and exit gracefully before getting terminated.– eryksun
Nov 13 '18 at 18:14
@eryksun It isnt a windows application(no GUI), and it isnt the owner of the console (otherwise I could use some varation of ctrl+c signals).
– Rohi
Nov 14 '18 at 7:02
@eryksun It isnt a windows application(no GUI), and it isnt the owner of the console (otherwise I could use some varation of ctrl+c signals).
– Rohi
Nov 14 '18 at 7:02
Even if it were a console app, sending Ctrl+C is not simple in Windows. You have to be attached to the console (e.g.
AttachConsole
, FreeConsole
). GenerateConsoleCtrlEvent
works only with process groups, not arbitrary process IDs. If you know the group ID (i.e. the PID of the lead process), then you probably created the process with CREATE_NEW_PROCESS_GROUP
, which disables Ctrl+C by default, so you have to use Ctrl+Break instead. Otherwise without a known group, you have to send to group 0 (all attached processes) and ignore the event in your own process.– eryksun
Nov 14 '18 at 12:18
Even if it were a console app, sending Ctrl+C is not simple in Windows. You have to be attached to the console (e.g.
AttachConsole
, FreeConsole
). GenerateConsoleCtrlEvent
works only with process groups, not arbitrary process IDs. If you know the group ID (i.e. the PID of the lead process), then you probably created the process with CREATE_NEW_PROCESS_GROUP
, which disables Ctrl+C by default, so you have to use Ctrl+Break instead. Otherwise without a known group, you have to send to group 0 (all attached processes) and ignore the event in your own process.– eryksun
Nov 14 '18 at 12:18
If it has no window or console, your last hope is that it's hosting a service (or services) that you can stop. Otherwise there's no standard way to signal a process. Windows has capabilities for this such as asynchronous procedure calls (APCs), named pipes, mailslots, events, and semaphores, but they're not a generic mechanism. An application has to be designed with a documented way to receive the signal.
– eryksun
Nov 14 '18 at 12:28
If it has no window or console, your last hope is that it's hosting a service (or services) that you can stop. Otherwise there's no standard way to signal a process. Windows has capabilities for this such as asynchronous procedure calls (APCs), named pipes, mailslots, events, and semaphores, but they're not a generic mechanism. An application has to be designed with a documented way to receive the signal.
– eryksun
Nov 14 '18 at 12:28
@Rohi does any of the answers have what you need? If not, what is missing? If you found a solution by yourself, please post it as an answer.
– roeen30
Nov 17 '18 at 17:53
@Rohi does any of the answers have what you need? If not, what is missing? If you found a solution by yourself, please post it as an answer.
– roeen30
Nov 17 '18 at 17:53
add a comment |
2 Answers
2
active
oldest
votes
You can use the Windows API as provided by pywin32 or hack it with a socket.
The socket solution is quick and dirty:
# waiting process
import socket
import select
import time
server = socket.socket()
server.bind(('localhost', 1337))
server.listen(5)
# this select() call returns ([server], , )
# if server is readable, else (, , ), and waits 0 seconds
while not select.select([server], , , 0)[0]:
print('working')
time.sleep(0.5)
# parent process
import socket
socket.create_connection(('localhost', 1337))
The windows solution is longer but more accurately represents the problem:
# waiting process
import time
import win32event
# open an existing event by name with the required access
# (didn't work for me with EVENT_MODIFY_STATE, got "Access denied" error)
event = win32event.OpenEvent(win32event.EVENT_ALL_ACCESS, 0, "MY_NAME")
# Wait 0 seconds on the event. If event has been set, WAIT_OBJECT_0 is returned
while win32event.WaitForSingleObject(event, 0) != win32event.WAIT_OBJECT_0:
print('working')
time.sleep(0.5)
# parent process
# note that it should be run first
import win32event
import time
# create event by name
event = win32event.CreateEvent(
None, # not inherited by child processes
False, # auto-reset the event after it is set
False, # created unset
"MY_NAME", # event name
)
time.sleep(5) # wait for waiting process to start
win32event.SetEvent(event)
This is only a minimal POC. It is recommended that you read about event objects to find the exact solution that suits you.
1
The event-based approach is the right one (with sockets you can have painful timeouts). You can callCreateEvent
with the same parameters on both sides (so you don't have to run one process before the other), just make sure you handle theERROR_ALREADY_EXISTS
error code. In this caseEVENT_MODIFY_STATE | SYNCHRONIZE
should be ok instead ofEVENT_ALL_ACCESS
– Simon Mourier
Nov 17 '18 at 9:08
Hey, this looks like it could solve my problem. Ill have a thorough look at it tomrrow.
– Rohi
Nov 17 '18 at 18:53
Works exactly as I wanted, thanks!
– Rohi
Nov 18 '18 at 7:30
You dont actually have to open the event before the proccess check it, you can try catch on the proccess, making this a really good solution.
– Rohi
Nov 18 '18 at 9:44
add a comment |
How about consider using psutil, I think it is quite suitable for your case.
As stated in document, following code can do what you want. Though you may not need the part of find_procs_by_name
.
import os
import signal
import psutil
def find_procs_by_name(name):
"Return a list of processes matching 'name'."
ls =
for p in psutil.process_iter(attrs=["name", "exe", "cmdline"]):
if name == p.info['name'] or
p.info['exe'] and os.path.basename(p.info['exe']) == name or
p.info['cmdline'] and p.info['cmdline'][0] == name:
ls.append(p)
return ls
def kill_proc_tree(pid, sig=signal.SIGTERM, include_parent=True,
timeout=None, on_terminate=None):
"""Kill a process tree (including grandchildren) with signal
"sig" and return a (gone, still_alive) tuple.
"on_terminate", if specified, is a callabck function which is
called as soon as a child terminates.
"""
if pid == os.getpid():
raise RuntimeError("I refuse to kill myself")
parent = psutil.Process(pid)
children = parent.children(recursive=True)
if include_parent:
children.append(parent)
for p in children:
p.send_signal(sig)
gone, alive = psutil.wait_procs(children, timeout=timeout,
callback=on_terminate)
return (gone, alive)
pid = find_procs_by_name('POWERPNT.EXE')[0].pid
print(find_procs_by_name('POWERPNT.EXE')[0].pid)
kill_proc_tree(pid)
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53282800%2fsend-a-signal-event-to-an-independent-process%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
You can use the Windows API as provided by pywin32 or hack it with a socket.
The socket solution is quick and dirty:
# waiting process
import socket
import select
import time
server = socket.socket()
server.bind(('localhost', 1337))
server.listen(5)
# this select() call returns ([server], , )
# if server is readable, else (, , ), and waits 0 seconds
while not select.select([server], , , 0)[0]:
print('working')
time.sleep(0.5)
# parent process
import socket
socket.create_connection(('localhost', 1337))
The windows solution is longer but more accurately represents the problem:
# waiting process
import time
import win32event
# open an existing event by name with the required access
# (didn't work for me with EVENT_MODIFY_STATE, got "Access denied" error)
event = win32event.OpenEvent(win32event.EVENT_ALL_ACCESS, 0, "MY_NAME")
# Wait 0 seconds on the event. If event has been set, WAIT_OBJECT_0 is returned
while win32event.WaitForSingleObject(event, 0) != win32event.WAIT_OBJECT_0:
print('working')
time.sleep(0.5)
# parent process
# note that it should be run first
import win32event
import time
# create event by name
event = win32event.CreateEvent(
None, # not inherited by child processes
False, # auto-reset the event after it is set
False, # created unset
"MY_NAME", # event name
)
time.sleep(5) # wait for waiting process to start
win32event.SetEvent(event)
This is only a minimal POC. It is recommended that you read about event objects to find the exact solution that suits you.
1
The event-based approach is the right one (with sockets you can have painful timeouts). You can callCreateEvent
with the same parameters on both sides (so you don't have to run one process before the other), just make sure you handle theERROR_ALREADY_EXISTS
error code. In this caseEVENT_MODIFY_STATE | SYNCHRONIZE
should be ok instead ofEVENT_ALL_ACCESS
– Simon Mourier
Nov 17 '18 at 9:08
Hey, this looks like it could solve my problem. Ill have a thorough look at it tomrrow.
– Rohi
Nov 17 '18 at 18:53
Works exactly as I wanted, thanks!
– Rohi
Nov 18 '18 at 7:30
You dont actually have to open the event before the proccess check it, you can try catch on the proccess, making this a really good solution.
– Rohi
Nov 18 '18 at 9:44
add a comment |
You can use the Windows API as provided by pywin32 or hack it with a socket.
The socket solution is quick and dirty:
# waiting process
import socket
import select
import time
server = socket.socket()
server.bind(('localhost', 1337))
server.listen(5)
# this select() call returns ([server], , )
# if server is readable, else (, , ), and waits 0 seconds
while not select.select([server], , , 0)[0]:
print('working')
time.sleep(0.5)
# parent process
import socket
socket.create_connection(('localhost', 1337))
The windows solution is longer but more accurately represents the problem:
# waiting process
import time
import win32event
# open an existing event by name with the required access
# (didn't work for me with EVENT_MODIFY_STATE, got "Access denied" error)
event = win32event.OpenEvent(win32event.EVENT_ALL_ACCESS, 0, "MY_NAME")
# Wait 0 seconds on the event. If event has been set, WAIT_OBJECT_0 is returned
while win32event.WaitForSingleObject(event, 0) != win32event.WAIT_OBJECT_0:
print('working')
time.sleep(0.5)
# parent process
# note that it should be run first
import win32event
import time
# create event by name
event = win32event.CreateEvent(
None, # not inherited by child processes
False, # auto-reset the event after it is set
False, # created unset
"MY_NAME", # event name
)
time.sleep(5) # wait for waiting process to start
win32event.SetEvent(event)
This is only a minimal POC. It is recommended that you read about event objects to find the exact solution that suits you.
1
The event-based approach is the right one (with sockets you can have painful timeouts). You can callCreateEvent
with the same parameters on both sides (so you don't have to run one process before the other), just make sure you handle theERROR_ALREADY_EXISTS
error code. In this caseEVENT_MODIFY_STATE | SYNCHRONIZE
should be ok instead ofEVENT_ALL_ACCESS
– Simon Mourier
Nov 17 '18 at 9:08
Hey, this looks like it could solve my problem. Ill have a thorough look at it tomrrow.
– Rohi
Nov 17 '18 at 18:53
Works exactly as I wanted, thanks!
– Rohi
Nov 18 '18 at 7:30
You dont actually have to open the event before the proccess check it, you can try catch on the proccess, making this a really good solution.
– Rohi
Nov 18 '18 at 9:44
add a comment |
You can use the Windows API as provided by pywin32 or hack it with a socket.
The socket solution is quick and dirty:
# waiting process
import socket
import select
import time
server = socket.socket()
server.bind(('localhost', 1337))
server.listen(5)
# this select() call returns ([server], , )
# if server is readable, else (, , ), and waits 0 seconds
while not select.select([server], , , 0)[0]:
print('working')
time.sleep(0.5)
# parent process
import socket
socket.create_connection(('localhost', 1337))
The windows solution is longer but more accurately represents the problem:
# waiting process
import time
import win32event
# open an existing event by name with the required access
# (didn't work for me with EVENT_MODIFY_STATE, got "Access denied" error)
event = win32event.OpenEvent(win32event.EVENT_ALL_ACCESS, 0, "MY_NAME")
# Wait 0 seconds on the event. If event has been set, WAIT_OBJECT_0 is returned
while win32event.WaitForSingleObject(event, 0) != win32event.WAIT_OBJECT_0:
print('working')
time.sleep(0.5)
# parent process
# note that it should be run first
import win32event
import time
# create event by name
event = win32event.CreateEvent(
None, # not inherited by child processes
False, # auto-reset the event after it is set
False, # created unset
"MY_NAME", # event name
)
time.sleep(5) # wait for waiting process to start
win32event.SetEvent(event)
This is only a minimal POC. It is recommended that you read about event objects to find the exact solution that suits you.
You can use the Windows API as provided by pywin32 or hack it with a socket.
The socket solution is quick and dirty:
# waiting process
import socket
import select
import time
server = socket.socket()
server.bind(('localhost', 1337))
server.listen(5)
# this select() call returns ([server], , )
# if server is readable, else (, , ), and waits 0 seconds
while not select.select([server], , , 0)[0]:
print('working')
time.sleep(0.5)
# parent process
import socket
socket.create_connection(('localhost', 1337))
The windows solution is longer but more accurately represents the problem:
# waiting process
import time
import win32event
# open an existing event by name with the required access
# (didn't work for me with EVENT_MODIFY_STATE, got "Access denied" error)
event = win32event.OpenEvent(win32event.EVENT_ALL_ACCESS, 0, "MY_NAME")
# Wait 0 seconds on the event. If event has been set, WAIT_OBJECT_0 is returned
while win32event.WaitForSingleObject(event, 0) != win32event.WAIT_OBJECT_0:
print('working')
time.sleep(0.5)
# parent process
# note that it should be run first
import win32event
import time
# create event by name
event = win32event.CreateEvent(
None, # not inherited by child processes
False, # auto-reset the event after it is set
False, # created unset
"MY_NAME", # event name
)
time.sleep(5) # wait for waiting process to start
win32event.SetEvent(event)
This is only a minimal POC. It is recommended that you read about event objects to find the exact solution that suits you.
edited Nov 16 '18 at 23:05
answered Nov 16 '18 at 22:51
roeen30roeen30
46629
46629
1
The event-based approach is the right one (with sockets you can have painful timeouts). You can callCreateEvent
with the same parameters on both sides (so you don't have to run one process before the other), just make sure you handle theERROR_ALREADY_EXISTS
error code. In this caseEVENT_MODIFY_STATE | SYNCHRONIZE
should be ok instead ofEVENT_ALL_ACCESS
– Simon Mourier
Nov 17 '18 at 9:08
Hey, this looks like it could solve my problem. Ill have a thorough look at it tomrrow.
– Rohi
Nov 17 '18 at 18:53
Works exactly as I wanted, thanks!
– Rohi
Nov 18 '18 at 7:30
You dont actually have to open the event before the proccess check it, you can try catch on the proccess, making this a really good solution.
– Rohi
Nov 18 '18 at 9:44
add a comment |
1
The event-based approach is the right one (with sockets you can have painful timeouts). You can callCreateEvent
with the same parameters on both sides (so you don't have to run one process before the other), just make sure you handle theERROR_ALREADY_EXISTS
error code. In this caseEVENT_MODIFY_STATE | SYNCHRONIZE
should be ok instead ofEVENT_ALL_ACCESS
– Simon Mourier
Nov 17 '18 at 9:08
Hey, this looks like it could solve my problem. Ill have a thorough look at it tomrrow.
– Rohi
Nov 17 '18 at 18:53
Works exactly as I wanted, thanks!
– Rohi
Nov 18 '18 at 7:30
You dont actually have to open the event before the proccess check it, you can try catch on the proccess, making this a really good solution.
– Rohi
Nov 18 '18 at 9:44
1
1
The event-based approach is the right one (with sockets you can have painful timeouts). You can call
CreateEvent
with the same parameters on both sides (so you don't have to run one process before the other), just make sure you handle the ERROR_ALREADY_EXISTS
error code. In this case EVENT_MODIFY_STATE | SYNCHRONIZE
should be ok instead of EVENT_ALL_ACCESS
– Simon Mourier
Nov 17 '18 at 9:08
The event-based approach is the right one (with sockets you can have painful timeouts). You can call
CreateEvent
with the same parameters on both sides (so you don't have to run one process before the other), just make sure you handle the ERROR_ALREADY_EXISTS
error code. In this case EVENT_MODIFY_STATE | SYNCHRONIZE
should be ok instead of EVENT_ALL_ACCESS
– Simon Mourier
Nov 17 '18 at 9:08
Hey, this looks like it could solve my problem. Ill have a thorough look at it tomrrow.
– Rohi
Nov 17 '18 at 18:53
Hey, this looks like it could solve my problem. Ill have a thorough look at it tomrrow.
– Rohi
Nov 17 '18 at 18:53
Works exactly as I wanted, thanks!
– Rohi
Nov 18 '18 at 7:30
Works exactly as I wanted, thanks!
– Rohi
Nov 18 '18 at 7:30
You dont actually have to open the event before the proccess check it, you can try catch on the proccess, making this a really good solution.
– Rohi
Nov 18 '18 at 9:44
You dont actually have to open the event before the proccess check it, you can try catch on the proccess, making this a really good solution.
– Rohi
Nov 18 '18 at 9:44
add a comment |
How about consider using psutil, I think it is quite suitable for your case.
As stated in document, following code can do what you want. Though you may not need the part of find_procs_by_name
.
import os
import signal
import psutil
def find_procs_by_name(name):
"Return a list of processes matching 'name'."
ls =
for p in psutil.process_iter(attrs=["name", "exe", "cmdline"]):
if name == p.info['name'] or
p.info['exe'] and os.path.basename(p.info['exe']) == name or
p.info['cmdline'] and p.info['cmdline'][0] == name:
ls.append(p)
return ls
def kill_proc_tree(pid, sig=signal.SIGTERM, include_parent=True,
timeout=None, on_terminate=None):
"""Kill a process tree (including grandchildren) with signal
"sig" and return a (gone, still_alive) tuple.
"on_terminate", if specified, is a callabck function which is
called as soon as a child terminates.
"""
if pid == os.getpid():
raise RuntimeError("I refuse to kill myself")
parent = psutil.Process(pid)
children = parent.children(recursive=True)
if include_parent:
children.append(parent)
for p in children:
p.send_signal(sig)
gone, alive = psutil.wait_procs(children, timeout=timeout,
callback=on_terminate)
return (gone, alive)
pid = find_procs_by_name('POWERPNT.EXE')[0].pid
print(find_procs_by_name('POWERPNT.EXE')[0].pid)
kill_proc_tree(pid)
add a comment |
How about consider using psutil, I think it is quite suitable for your case.
As stated in document, following code can do what you want. Though you may not need the part of find_procs_by_name
.
import os
import signal
import psutil
def find_procs_by_name(name):
"Return a list of processes matching 'name'."
ls =
for p in psutil.process_iter(attrs=["name", "exe", "cmdline"]):
if name == p.info['name'] or
p.info['exe'] and os.path.basename(p.info['exe']) == name or
p.info['cmdline'] and p.info['cmdline'][0] == name:
ls.append(p)
return ls
def kill_proc_tree(pid, sig=signal.SIGTERM, include_parent=True,
timeout=None, on_terminate=None):
"""Kill a process tree (including grandchildren) with signal
"sig" and return a (gone, still_alive) tuple.
"on_terminate", if specified, is a callabck function which is
called as soon as a child terminates.
"""
if pid == os.getpid():
raise RuntimeError("I refuse to kill myself")
parent = psutil.Process(pid)
children = parent.children(recursive=True)
if include_parent:
children.append(parent)
for p in children:
p.send_signal(sig)
gone, alive = psutil.wait_procs(children, timeout=timeout,
callback=on_terminate)
return (gone, alive)
pid = find_procs_by_name('POWERPNT.EXE')[0].pid
print(find_procs_by_name('POWERPNT.EXE')[0].pid)
kill_proc_tree(pid)
add a comment |
How about consider using psutil, I think it is quite suitable for your case.
As stated in document, following code can do what you want. Though you may not need the part of find_procs_by_name
.
import os
import signal
import psutil
def find_procs_by_name(name):
"Return a list of processes matching 'name'."
ls =
for p in psutil.process_iter(attrs=["name", "exe", "cmdline"]):
if name == p.info['name'] or
p.info['exe'] and os.path.basename(p.info['exe']) == name or
p.info['cmdline'] and p.info['cmdline'][0] == name:
ls.append(p)
return ls
def kill_proc_tree(pid, sig=signal.SIGTERM, include_parent=True,
timeout=None, on_terminate=None):
"""Kill a process tree (including grandchildren) with signal
"sig" and return a (gone, still_alive) tuple.
"on_terminate", if specified, is a callabck function which is
called as soon as a child terminates.
"""
if pid == os.getpid():
raise RuntimeError("I refuse to kill myself")
parent = psutil.Process(pid)
children = parent.children(recursive=True)
if include_parent:
children.append(parent)
for p in children:
p.send_signal(sig)
gone, alive = psutil.wait_procs(children, timeout=timeout,
callback=on_terminate)
return (gone, alive)
pid = find_procs_by_name('POWERPNT.EXE')[0].pid
print(find_procs_by_name('POWERPNT.EXE')[0].pid)
kill_proc_tree(pid)
How about consider using psutil, I think it is quite suitable for your case.
As stated in document, following code can do what you want. Though you may not need the part of find_procs_by_name
.
import os
import signal
import psutil
def find_procs_by_name(name):
"Return a list of processes matching 'name'."
ls =
for p in psutil.process_iter(attrs=["name", "exe", "cmdline"]):
if name == p.info['name'] or
p.info['exe'] and os.path.basename(p.info['exe']) == name or
p.info['cmdline'] and p.info['cmdline'][0] == name:
ls.append(p)
return ls
def kill_proc_tree(pid, sig=signal.SIGTERM, include_parent=True,
timeout=None, on_terminate=None):
"""Kill a process tree (including grandchildren) with signal
"sig" and return a (gone, still_alive) tuple.
"on_terminate", if specified, is a callabck function which is
called as soon as a child terminates.
"""
if pid == os.getpid():
raise RuntimeError("I refuse to kill myself")
parent = psutil.Process(pid)
children = parent.children(recursive=True)
if include_parent:
children.append(parent)
for p in children:
p.send_signal(sig)
gone, alive = psutil.wait_procs(children, timeout=timeout,
callback=on_terminate)
return (gone, alive)
pid = find_procs_by_name('POWERPNT.EXE')[0].pid
print(find_procs_by_name('POWERPNT.EXE')[0].pid)
kill_proc_tree(pid)
answered Nov 16 '18 at 1:56
MatrixTaiMatrixTai
2,009623
2,009623
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53282800%2fsend-a-signal-event-to-an-independent-process%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Does the process have a window that can be sent
WM_CLOSE
? Most GUI apps will exit gracefully (including asking to save files) if the main window is closed. This is what taskkill.exe does by default without the /F option. This can also be used for a console process if it's the effective owner of the console window (usually if it allocated the console). When the console window is closed, all applications attached to it (not just the owner) have no more than 5 seconds to handle the control event and exit gracefully before getting terminated.– eryksun
Nov 13 '18 at 18:14
@eryksun It isnt a windows application(no GUI), and it isnt the owner of the console (otherwise I could use some varation of ctrl+c signals).
– Rohi
Nov 14 '18 at 7:02
Even if it were a console app, sending Ctrl+C is not simple in Windows. You have to be attached to the console (e.g.
AttachConsole
,FreeConsole
).GenerateConsoleCtrlEvent
works only with process groups, not arbitrary process IDs. If you know the group ID (i.e. the PID of the lead process), then you probably created the process withCREATE_NEW_PROCESS_GROUP
, which disables Ctrl+C by default, so you have to use Ctrl+Break instead. Otherwise without a known group, you have to send to group 0 (all attached processes) and ignore the event in your own process.– eryksun
Nov 14 '18 at 12:18
If it has no window or console, your last hope is that it's hosting a service (or services) that you can stop. Otherwise there's no standard way to signal a process. Windows has capabilities for this such as asynchronous procedure calls (APCs), named pipes, mailslots, events, and semaphores, but they're not a generic mechanism. An application has to be designed with a documented way to receive the signal.
– eryksun
Nov 14 '18 at 12:28
@Rohi does any of the answers have what you need? If not, what is missing? If you found a solution by yourself, please post it as an answer.
– roeen30
Nov 17 '18 at 17:53