我试图在Process Class中包装基本的Windows进程功能。 我希望进程在父进程的同一进程组和同一个控制台中运行,我想在调用Process :: Kill()时轻轻地杀死它们。
从各种来源读取我最终得到了这段代码,首先检查进程是否为GUI,如果是,则发送WM_CLOSE(EnumChildWindowsHandler执行此操作),如果没有,则进程有控制台,发送CTRL_C事件。它有效,但当子进程是" cmd.exe"该过程在GenerateConsoleCtrlEvent函数崩溃,调试器表示发生了写入访问冲突。
重点是什么?在我的阅读材料中我没有理解什么?
bool Process::Kill( ) {
// Here I check if the process is a GUI app
if (!EnumThreadWindows(mChildInfo->dwThreadId, EnumChildWindowsHandler, mChildInfo->dwProcessId)) {
if (WaitForSingleObject(mChildInfo->hProcess, 2000) == WAIT_TIMEOUT) {
{ TerminateProcess(mChildInfo->hProcess, 0); } }
//If not, test if it's a CUI then send CTRL_C
else {
int minPid = 10;
int els;
unsigned long *pids = new unsigned long(minPid);
els = GetConsoleProcessList( pids, minPid );
if (els > minPid) {
free (pids);
pids = new unsigned long(els);
els = GetConsoleProcessList(pids, els);
}
if (find(pids, pids+els, mChildInfo->dwProcessId)) {
cout << "Sending CTRL_C_EVENT.." << endl;
SetConsoleCtrlHandler(NULL, TRUE);
GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0);
if (WaitForSingleObject(mChildInfo->hProcess, 2000) == WAIT_TIMEOUT) { TerminateProcess(mChildInfo->hProcess, 0); }
SetConsoleCtrlHandler(NULL, FALSE);
CloseHandle(mChildInfo->hProcess);
CloseHandle(mChildInfo->hThread);
}
return true;
}
编辑:我发现了ReactOS cmd.exe源代码,这是这类东西的黄金。我会发布我最终学到的内容的更新。 网址:http://doxygen.reactos.org/db/d4f/base_2shell_2cmd_2cmd_8c_source.html
答案 0 :(得分:1)
cmd源代码很好地解释了如何正确操作,顺便说一句,我只是使用CTRL_BREAK并且像魅力一样工作。在创建过程中,我传递CREATE_NEW_PROCESS_GROUP并为showWindow模式设置SW_SHOWDEFAULT,然后以这种方式终止进程:
private <T extends Instantiable> List<T> getEntityList(Class<T> entityType, int numberOfItems) throws Exception {
List<T> entities = new ArrayList<T>();
for (int i = 0; i < numberOfItems; i++) {
Constructor<T> ctor = entityType.getConstructor();
entities.add(ctor.newInstance());
}
return entities;
}
另外,如果我们想在处理信号时以类似方式执行操作,我们可以像这样注册一个sighandler(我们仍然需要WriteConsoleInput):
//Determine if lParam has for main window the hWnd, and send WM_CLOSE
int CALLBACK EnumChildWindowsHandler(HWND hWnd, LPARAM lParam)
{
//WORD type
unsigned long pid = 0;
GetWindowThreadProcessId(hWnd, &pid);
if (pid == (unsigned long) lParam) {
cout << "HANDLEWIN: " << hWnd << " Bwehe" << endl;
cout << "PID: " << pid << endl;
if (!GetParent(hWnd)) PostMessageA(hWnd, WM_CLOSE, 0, 0);
return 0;
}
return 1;
}
bool Process::KillGently( ) {
if (EnumThreadWindows(mProcInfo->dwThreadId, EnumChildWindowsHandler, mProcInfo->dwProcessId)) {
if (!GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, mProcInfo->dwProcessId))
cerr << "Error while sending CTRL_BREAK_EVENT: " << GetLastError() << endl;
}
主线程在等待刚刚开始的进程终止时进入临界区。
BTW我仍然不知道为什么我的应用程序崩溃了之前的代码。