mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-23 22:52:11 +02:00
New file added to do interrupt on a pid.
This commit is contained in:
parent
fcd010f569
commit
982b2135d2
1 changed files with 181 additions and 0 deletions
181
core/org.eclipse.cdt.core.win32/library/raise.c
Normal file
181
core/org.eclipse.cdt.core.win32/library/raise.c
Normal file
|
@ -0,0 +1,181 @@
|
|||
/* Copyright, 2002, QNX Software Systems Ltd. All Rights Reserved
|
||||
|
||||
* This source code has been published by QNX Software Systems
|
||||
* Ltd. (QSSL). However, any use, reproduction, modification, distribution
|
||||
* or transfer of this software, or any software which includes or is based
|
||||
* upon any of this code, is only permitted if expressly authorized by a
|
||||
* written license agreement from QSSL. Contact the QNX Developer's Network
|
||||
* or contact QSSL's legal department for more information.
|
||||
*
|
||||
*
|
||||
* Win32ProcessEx.c
|
||||
*
|
||||
* This is a JNI implementation of spawner
|
||||
*/
|
||||
#include "stdafx.h"
|
||||
#include "Spawner.h"
|
||||
|
||||
|
||||
#include "jni.h"
|
||||
|
||||
extern void JNICALL ThrowByName(JNIEnv *env, const char *name, const char *msg);
|
||||
|
||||
// #define DEBUG_MONITOR
|
||||
|
||||
static HWND consoleHWND;
|
||||
|
||||
static BOOL CALLBACK
|
||||
find_child_console (HWND hwnd, LPARAM arg)
|
||||
{
|
||||
DWORD thread_id;
|
||||
DWORD process_id;
|
||||
DWORD pid = arg;
|
||||
|
||||
thread_id = GetWindowThreadProcessId (hwnd, &process_id);
|
||||
if (process_id == pid)
|
||||
{
|
||||
char window_class[32];
|
||||
|
||||
GetClassName (hwnd, window_class, sizeof (window_class));
|
||||
if (strcmp (window_class, "ConsoleWindowClass") == 0)
|
||||
{
|
||||
consoleHWND = hwnd;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
/* keep looking */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_raise__Ljava_lang_Object_2
|
||||
(JNIEnv * env, jobject process, jobject jpid)
|
||||
{
|
||||
jint pid;
|
||||
jclass integerClass = (*env) -> FindClass(env, "java/lang/Integer");
|
||||
jmethodID intValue;
|
||||
if(NULL == integerClass) {
|
||||
ThrowByName(env, "java/lang/IOException", "Cannot find Integer class");
|
||||
return -1;
|
||||
}
|
||||
if(!((*env) -> IsInstanceOf(env, jpid, integerClass))) {
|
||||
ThrowByName(env, "java/lang/IOException", "Wrong argument");
|
||||
return -1;
|
||||
}
|
||||
|
||||
intValue = (*env) -> GetMethodID(env, integerClass, "intValue", "()I");
|
||||
if(NULL == intValue) {
|
||||
ThrowByName(env, "java/lang/IOException", "Cannot find intValue method in Integer class");
|
||||
return -1;
|
||||
}
|
||||
|
||||
pid = (*env) -> CallIntMethod(env, jpid, intValue);
|
||||
|
||||
return interruptProcess(pid);
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
int interruptProcess(int pid)
|
||||
{
|
||||
#ifdef DEBUG_MONITOR
|
||||
char buffer[1000];
|
||||
#endif
|
||||
int rc;
|
||||
// Try another method
|
||||
rc = 0;
|
||||
consoleHWND = NULL;
|
||||
|
||||
#ifdef DEBUG_MONITOR
|
||||
sprintf(buffer, "Try to interrupt process %i\n", pid);
|
||||
OutputDebugString(buffer);
|
||||
#endif
|
||||
EnumWindows (find_child_console, (LPARAM) pid);
|
||||
|
||||
if(NULL != consoleHWND)
|
||||
{
|
||||
BYTE control_scan_code = (BYTE) MapVirtualKey (VK_CONTROL, 0);
|
||||
/* Fake Ctrl-C for SIGINT, and Ctrl-Break for SIGQUIT. */
|
||||
BYTE vk_c_code = 'C';
|
||||
BYTE vk_break_code = VK_CANCEL;
|
||||
BYTE c_scan_code = (BYTE) MapVirtualKey (vk_c_code, 0);
|
||||
BYTE break_scan_code = (BYTE) MapVirtualKey (vk_break_code, 0);
|
||||
HWND foreground_window;
|
||||
|
||||
|
||||
foreground_window = GetForegroundWindow ();
|
||||
if (foreground_window)
|
||||
{
|
||||
/* NT 5.0, and apparently also Windows 98, will not allow
|
||||
a Window to be set to foreground directly without the
|
||||
user's involvement. The workaround is to attach
|
||||
ourselves to the thread that owns the foreground
|
||||
window, since that is the only thread that can set the
|
||||
foreground window. */
|
||||
DWORD foreground_thread, child_thread;
|
||||
foreground_thread =
|
||||
GetWindowThreadProcessId (foreground_window, NULL);
|
||||
if (foreground_thread == GetCurrentThreadId ()
|
||||
|| !AttachThreadInput (GetCurrentThreadId (),
|
||||
foreground_thread, TRUE))
|
||||
foreground_thread = 0;
|
||||
|
||||
child_thread = GetWindowThreadProcessId (consoleHWND, NULL);
|
||||
if (child_thread == GetCurrentThreadId ()
|
||||
|| !AttachThreadInput (GetCurrentThreadId (),
|
||||
child_thread, TRUE))
|
||||
child_thread = 0;
|
||||
|
||||
/* Set the foreground window to the child. */
|
||||
if (SetForegroundWindow (consoleHWND))
|
||||
{
|
||||
/*
|
||||
if(0 != c_scan_code) {
|
||||
// Generate keystrokes as if user had typed Ctrl-C.
|
||||
keybd_event (VK_CONTROL, control_scan_code, 0, 0);
|
||||
keybd_event (vk_c_code, c_scan_code, 0, 0);
|
||||
keybd_event (vk_c_code, c_scan_code, KEYEVENTF_KEYUP, 0);
|
||||
keybd_event (VK_CONTROL, control_scan_code, KEYEVENTF_KEYUP, 0);
|
||||
}
|
||||
*/
|
||||
/* Sleep for a bit to give time for respond */
|
||||
Sleep (100);
|
||||
if(0 != break_scan_code) {
|
||||
/* Generate keystrokes as if user had typed Ctrl-Break */
|
||||
keybd_event (VK_CONTROL, control_scan_code, 0, 0);
|
||||
keybd_event (vk_break_code, break_scan_code, KEYEVENTF_EXTENDEDKEY, 0);
|
||||
keybd_event (vk_break_code, break_scan_code,
|
||||
KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
|
||||
keybd_event (VK_CONTROL, control_scan_code, KEYEVENTF_KEYUP, 0);
|
||||
}
|
||||
|
||||
/* Sleep for a bit to give time for respond */
|
||||
Sleep (100);
|
||||
|
||||
SetForegroundWindow (foreground_window);
|
||||
}
|
||||
/* Detach from the foreground and child threads now that
|
||||
the foreground switching is over. */
|
||||
if (foreground_thread)
|
||||
AttachThreadInput (GetCurrentThreadId (),
|
||||
foreground_thread, FALSE);
|
||||
if (child_thread)
|
||||
AttachThreadInput (GetCurrentThreadId (),
|
||||
child_thread, FALSE);
|
||||
#ifdef DEBUG_MONITOR
|
||||
sprintf(buffer, "Sent Ctrl-C & Ctrl-Break to process %i\n", pid);
|
||||
OutputDebugString(buffer);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG_MONITOR
|
||||
else {
|
||||
sprintf(buffer, "Cannot find console for process %i\n", pid);
|
||||
|
||||
OutputDebugString(buffer);
|
||||
}
|
||||
#endif
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
Loading…
Add table
Reference in a new issue