Sends a specified signal to a console process group that shares the console associated with the calling process.
for detail: http://msdn.microsoft.com/en-us/library/windows/desktop/ms683155(v=vs.85).aspx
Browsing though MSDN showed
that GenerateConsoleCtrlEvent should be perfect for the job. Just write a
little wrapper and we‘re done, right? If only. When I tried to use it, it always
failed with ERROR_INVALID_PARAMETER
unless
I was trying to signal myself.
The next thing I tried was injecting a thread into the target process to
call GenerateConsoleCtrlEvent
. I had all the code to do this
from SaveConsole.
Well, that worked so long as the target process was a console process. Our IDE
started Java as a windowed process (javaw.exe
instead
of java.exe
), so the call would fail
with ERROR_INVALID_HANDLE
.
After much digging around in the debugger I discovered that the entry point
that actually does the behavior associated with a signal like ctrl-break
is kernel32!CtrlRoutine
. The function had the same prototype
as ThreadProc,
so it can be used with CreateRemoteThread directly,
without having to inject code. However, that‘s not an exported symbol! It‘s at
different addresses (and even has different names) on different versions of
Windows. What to do?
Here is the solution I finally came up with. I install a console ctrl handler
for my app, then generate a ctrl-break signal for my app. When my handler gets
called, I look back at the top of the stack to find out the parameters passed
to kernel32!BaseThreadStart
. I grab the first param, which is
the desired start address of the thread, which is the address
of kernel32!CtrlRoutine
. Then I return from my handler,
indicating that I have handled the signal and my app should not be terminated.
Back in the main thread, I wait until the address
of kernel32!CtrlRoutine
has been retrieved. Once I‘ve got
it, I create a remote thread in the target process with the discovered start
address. This causes the ctrl handlers in the target process to be evaluated as
if ctrl-break had been pressed!
The nice thing is that only the target process is affected, and any process
(even a windowed process) can be targeted. One downside is that my little app
can‘t be used in a batch file, since it will kill it when it sends the
ctrl-break event in order to discover the address
of kernel32!CtrlRoutine
.
Small update: I ended up needing to use it in a script, so now I know
what happens. If called directly, it will work but it will hang the script
because cmd.exe
will pause with a Terminate
batch job (Y/N)?
prompt. Not good for something that‘s supposed to
run unattended. :) However, you can use start
to run it
in a separate console. You won‘t be able to redirect the output, but at least
you won‘t get a mysterious prompt. :)
reprinted:http://www.latenighthacking.com/projects/2003/sendSignal/
sourcecode: http://www.latenighthacking.com/projects/2003/sendSignal/SendSignalSrc.zip
/*full_path = "sendsignal 9527" 9527 is a pid which process need to be signal up*/
int CTDMaintainManager::CreateProcess(const char * full_path) { //Create process STARTUPINFO info; PROCESS_INFORMATION pinfo; memset(&info,0,sizeof(info)); info.cb = sizeof(info); //info.wShowWindow = SW_SHOWNOACTIVATE; info.dwFlags = STARTF_USESHOWWINDOW; info.wShowWindow = 0; //TRUE表示显示创建的进程的窗口 if(!::CreateProcess(NULL,(LPSTR) full_path, NULL,NULL,FALSE,0,NULL,NULL,&info,&pinfo)) { CT_LOG_ERR("CTDMaintainManager::CreateProcess program %s failed %d.\n", full_path, GetLastError()); return -1; } CT_LOG_CRITICAL(NULL, "CTDMaintainManager::CreateProcess \"%s\" [%d] ok .\n", full_path, pinfo.dwProcessId); return 0; }
How to send CTRL+BREAK signal to detached command-line process,布布扣,bubuko.com
How to send CTRL+BREAK signal to detached command-line process
原文:http://www.cnblogs.com/iclk/p/3569992.html