C++ C++;WINAPI:当调用(父)进程被强制终止时,如何杀死子进程?

C++ C++;WINAPI:当调用(父)进程被强制终止时,如何杀死子进程?,c++,winapi,C++,Winapi,有谁能告诉我,当调用(父)进程被强制终止时,如何杀死子进程?顺便说一下,我无法更改子应用程序的源代码 我已经检查了StackOverflow中现有的线程,看来JobObject是正确的方法。然而,当我测试它时(使用控制台应用程序调用notepad.exe),我发现当控制台应用程序退出时,notepad没有 我使用CreateProcess生成新进程 我还看到有人说在父进程和子进程之间设置管道就可以了,但我还没有尝试过 如果有人能给我一些提示,我将不胜感激 更新:如果在createprocess中

有谁能告诉我,当调用(父)进程被强制终止时,如何杀死子进程?顺便说一下,我无法更改子应用程序的源代码

我已经检查了StackOverflow中现有的线程,看来JobObject是正确的方法。然而,当我测试它时(使用控制台应用程序调用notepad.exe),我发现当控制台应用程序退出时,notepad没有

我使用
CreateProcess
生成新进程

我还看到有人说在父进程和子进程之间设置管道就可以了,但我还没有尝试过

如果有人能给我一些提示,我将不胜感激

更新:如果在
createprocess
中没有
|创建_脱离_作业
,WINAPI
AssignProcessToJobObject
将无法工作。现在它工作了

谢谢大家

再次更新:

这真的很棘手。我总是被Windows API弄糊涂

第一组:

进程标志:
CREATE\u SUSPENDED

JobObject标志:
JOB\u OBJECT\u LIMIT\u KILL\u ON\u JOB\u CLOSE\124; JOB\u OBJECT\u SECURITY\u RESTRICTED\u TOKEN或JOB\u OBJECT\u SECURITY\u NO\u ADMIN或JOB\u OBJECT\u LIMIT\u breake\u OK

结果:
AssingProcessToJobObject
失败,错误代码5访问被拒绝

第2组:

进程标志:
CREATE_SUSPENDED| CREATE_breakout_FROM_JOB

JobObject标志:
JOB\u OBJECT\u LIMIT\u KILL\u ON\u JOB\u CLOSE\124; JOB\u OBJECT\u SECURITY\u RESTRICTED\u TOKEN或JOB\u OBJECT\u SECURITY\u NO\u ADMIN

结果:
AssingProcessToJobObject
成功,但在父进程被终止时子进程未能终止

第3组:

进程标志:
CREATE_SUSPENDED| CREATE_breakout_FROM_JOB

JobObject标志:
JOB\u OBJECT\u LIMIT\u KILL\u ON\u JOB\u CLOSE

结果:
AssingProcessToJobObject
成功,父进程被终止时,子进程被自动终止

第4组:

进程标志:
CREATE_SUSPENDED| CREATE_breakout_FROM_JOB

JobObject标志:
JOB\u OBJECT\u LIMIT\u KILL\u ON\u JOB\u CLOSE\124; JOB\u OBJECT\u LIMIT\u breake\u OK

结果:第3组相同

下面的代码使用我从中复制的JobObject

#定义_WIN32_WINNT 0x0500
#包括
内部主(空)
{
处理hJob;
JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli={0};
进程信息pi={0};
STARTUPINFO si={0};
/*
*创建作业对象。
*/
hJob=CreateJobObject(NULL,NULL);
/*
*导致与作业关联的所有进程在
*作业的最后一个句柄已关闭。
*/
jeli.BasicLimitInformation.LimitFlags=JOB\u OBJECT\u LIMIT\u KILL\u ON\u JOB\u CLOSE;
SetInformationJobObject(hJob,jobobjectextendedlimiteinformation,&jeli,sizeof(jeli));
/*
*创建挂起的进程。
*/
si.cb=sizeof(si);
CreateProcess(文本(“C:\\Windows\\System32\\Notepad.exe”),NULL,NULL,NULL,FALSE,
创建_SUSPENDED |创建_breakout _FROM _JOB/*Important*/,NULL,NULL,&si,&pi);
/*
*将流程添加到我们的作业对象。
*/
AssignProcessToJobObject(hJob,pi.hProcess);//如果没有从作业中创建分离,则不工作
/*
*开始我们暂停的进程。
*/
恢复线程(pi.hThread);
/*
*此时,如果我们关闭,窗口将自动清理
*通过关闭我们已打开的任何句柄。当
*如果已关闭,则属于该作业的任何进程都将终止。
*注意:孙子进程自动成为作业的一部分,并且
*也将终止。通过使用
*作业\对象\限制\静音\分离\确定限制标志。
*/
/*
*在这里做你喜欢做的。为了演示,我们将等待
*要完成子进程,请单击“关闭”按钮查看
*一切都在行动。
*/
WaitForSingleObject(pi.hProcess,3000);
/*
*如前所述,当我们的进程
*退出,但显式执行是一种好的方式。
*/
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
闭合手柄(hJob);
返回0;
}

我也有类似的情况。我的主应用程序创建一个子进程,用于记录“事件”。子进程保留其父进程的记录(可以有多个)。在子进程中使用计时器,我可以检查父进程是否崩溃或关闭。当检测到此情况时,子进程将完全关闭。

不要通过F5或Ctrl+F5从Visual Studio中进行测试。当VisualStudio启动您的程序时,它本身使用Job来管理事情,这会与您的代码产生严重的交互

打开控制台并“手动”启动exe。您的代码是正确的(“在这里工作”,VS2010在7位)

编辑:您可以添加错误检查,但不要假设所有API都会成功

编辑:启动时,您可以使用API了解流程是否已在作业中。在这种情况下,默认情况下,子进程是在先前存在的作业中创建的,然后必须使用
CREATE\u breakout\u FROM\u job
(如果不使用,则不能使用
AssignProcessToJobObject

从VisualStudio启动流程时,或通过在资源管理器中双击启动流程时,流程将在作业中启动

添加,我的代码基于你的,从VS或资源管理器工作

#include <Windows.h>
#include <stdio.h>

int main( void ) {

    BOOL bIsProcessInJob;
    BOOL bSuccess = IsProcessInJob( GetCurrentProcess(), NULL, &bIsProcessInJob );
    if ( bSuccess == 0 ) {
        printf( "IsProcessInJob failed: error %d\n", GetLastError() );
        return 0;
    }
    if ( bIsProcessInJob ) {
        MessageBox( NULL, L"Process is already in Job", L"Job Test", 0 );
    }

    HANDLE hJob = CreateJobObject( NULL, NULL );
    if ( hJob == NULL ) {
        printf( "CreateJobObject failed: error %d\n", GetLastError() );
        return 0;
    }

    JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli = { 0 };
    jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
    bSuccess = SetInformationJobObject( hJob, JobObjectExtendedLimitInformation, &jeli, sizeof( jeli ) );
    if ( bSuccess == 0 ) {
        printf( "SetInformationJobObject failed: error %d\n", GetLastError() );
        return 0;
    }

    PROCESS_INFORMATION pi = { 0 };
    STARTUPINFO si = { 0 };
    si.cb = sizeof( si );
    DWORD dwCreationFlags = bIsProcessInJob ? CREATE_BREAKAWAY_FROM_JOB : 0;
    bSuccess = CreateProcess( L"C:\\Windows\\System32\\Notepad.exe", NULL, NULL, NULL, FALSE, 
                              dwCreationFlags, NULL, NULL, &si, &pi);
    if ( bSuccess == 0 ) {
        printf( "CreateProcess failed: error %d\n", GetLastError() );
        return 0;
    }

    bSuccess = AssignProcessToJobObject( hJob, pi.hProcess );
    if ( bSuccess == 0 ) {
        printf( "AssignProcessToJobObject failed: error %d\n", GetLastError() );
        return 0;
    }

    CloseHandle( pi.hThread );
    CloseHandle( pi.hProcess );

    printf( "Type a key to exit..." );
    getchar();

    CloseHandle( hJob );

    return 0;

}
#包括
#包括
内部主(空){
布尔·比斯宾约布;
BOOL bSuccess=IsProcessInJob(GetCurrentProcess(),NULL,&bIsProcessInJob);
if(bSuccess==0){
printf(“IsPro
#include <Windows.h>
#include <stdio.h>

int main( void ) {

    BOOL bIsProcessInJob;
    BOOL bSuccess = IsProcessInJob( GetCurrentProcess(), NULL, &bIsProcessInJob );
    if ( bSuccess == 0 ) {
        printf( "IsProcessInJob failed: error %d\n", GetLastError() );
        return 0;
    }
    if ( bIsProcessInJob ) {
        MessageBox( NULL, L"Process is already in Job", L"Job Test", 0 );
    }

    HANDLE hJob = CreateJobObject( NULL, NULL );
    if ( hJob == NULL ) {
        printf( "CreateJobObject failed: error %d\n", GetLastError() );
        return 0;
    }

    JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli = { 0 };
    jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
    bSuccess = SetInformationJobObject( hJob, JobObjectExtendedLimitInformation, &jeli, sizeof( jeli ) );
    if ( bSuccess == 0 ) {
        printf( "SetInformationJobObject failed: error %d\n", GetLastError() );
        return 0;
    }

    PROCESS_INFORMATION pi = { 0 };
    STARTUPINFO si = { 0 };
    si.cb = sizeof( si );
    DWORD dwCreationFlags = bIsProcessInJob ? CREATE_BREAKAWAY_FROM_JOB : 0;
    bSuccess = CreateProcess( L"C:\\Windows\\System32\\Notepad.exe", NULL, NULL, NULL, FALSE, 
                              dwCreationFlags, NULL, NULL, &si, &pi);
    if ( bSuccess == 0 ) {
        printf( "CreateProcess failed: error %d\n", GetLastError() );
        return 0;
    }

    bSuccess = AssignProcessToJobObject( hJob, pi.hProcess );
    if ( bSuccess == 0 ) {
        printf( "AssignProcessToJobObject failed: error %d\n", GetLastError() );
        return 0;
    }

    CloseHandle( pi.hThread );
    CloseHandle( pi.hProcess );

    printf( "Type a key to exit..." );
    getchar();

    CloseHandle( hJob );

    return 0;

}
hJob = CreateJobObject(NULL, NULL);

JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli = {
    0, 0, JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE, 0
};
SetInformationJobObject(hJob, &jeli);

if (AssignProcessToJobObject(hJob, GetCurrentProcess()) == FALSE) {
    DWORD Error = GetLastError();
}