6

I have two processes, A and B. At some point A creates B. After B is created, if A's process tree is killed, I want B to still be around.

I am using CreateProcess() to create B, and I can't seem to find any way to make it create the process without it being a child. Same thing with ShellExecuteEx(), but I am probably missing some flag.

Does anyone know what I could use to do this?

EDIT: I forgot to mention that both processes need a HANDLE or process ID to the other

Sinenomen
  • 244
  • 5
  • 11
  • Did you look at CREATE_NEW_PROCESS_GROUP in the creation flags argument of CreateProcess()? – vanza Jun 28 '10 at 21:20

3 Answers3

2

You can try that process A create process C, which create process B and then process C will be immediatly ended (terminated). In a process B there are exist only information about the direct parent process (process Id of C which is not more running) and not about the process A. So "if A's process tree is killed" the process B will probably stay running.

For example you start Process Explorer (see http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx) then start Total Commander. From the Total Commander you start cmd.exe. From cmd.exe you start notepad.exe. Then type "exit" in the cmd.exe. After terminating of cmd.exe you can see that notepad.exe will no more displayed under Total Commander (totalcmd.exe). After you choose in Process Explorer "Kill Process Tree" for the Total Commander (totalcmd.exe) you can see that notepad.exe stay running.

Oleg
  • 220,925
  • 34
  • 403
  • 798
  • OK, I tried that, and I think it will do, one thing I forgot is that both processes need each other's process ID. With this solution, process B will have process A's ID, but A will only have B's. I think I can figure this one out with some kind of message passing though. Thanks! – Sinenomen Jun 28 '10 at 22:18
  • Every process can set exit code (with respect of `ExitProcess` or C function `exit`). So if process C (middle process) returns as an exit code the process id of the process B, then process A can give it for example with respect of `GetExitCodeProcess` function. – Oleg Jun 28 '10 at 22:31
  • Yeah, I think that's what I'll do, it's seems a bit hacky, but it's good enough, at least for now – Sinenomen Jun 29 '10 at 02:41
1

You can set the paramaeter dwcreationflags as DETACHED_PROCESS in the createprocess API.

Muthukumar Palaniappan
  • 1,622
  • 5
  • 25
  • 49
  • 1
    DETACHED_PROCESS has nothing to do with the parent child chain of processes. With that flag enabled the child process will not receive any console whatsoever thus the child process does not share the console with its parent process as opposed to CreateProcess()'s default behavior. – Coconut Feb 03 '22 at 11:57
1

When calling kernel32!CreateProcess() you can specify a different parent by using a process attribute. Here is a function that does just that.

bool CreateProcessWithParent(DWORD parentId, PWSTR commandline) {
    auto hProcess = ::OpenProcess(PROCESS_CREATE_PROCESS, FALSE, parentId);
    if (!hProcess)
        return false;
 
    SIZE_T size;
    //
    // call InitializeProcThreadAttributeList twice
    // first, get required size
    //
    ::InitializeProcThreadAttributeList(nullptr, 1, 0, &size);
 
    //
    // now allocate a buffer with the required size and call again
    //
    auto buffer = std::make_unique<BYTE[]>(size);
    auto attributes = reinterpret_cast<PPROC_THREAD_ATTRIBUTE_LIST>(buffer.get());
    ::InitializeProcThreadAttributeList(attributes, 1, 0, &size);
 
    //
    // add the parent attribute
    //
    ::UpdateProcThreadAttribute(attributes, 0, 
        PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, 
        &hProcess, sizeof(hProcess), nullptr, nullptr);
 
    STARTUPINFOEX si = { sizeof(si) };
    //
    // set the attribute list
    //
    si.lpAttributeList = attributes;
    PROCESS_INFORMATION pi;
 
    //
    // create the process
    //
    BOOL created = ::CreateProcess(nullptr, commandline, nullptr, nullptr, 
        FALSE, EXTENDED_STARTUPINFO_PRESENT, nullptr, nullptr, 
        (STARTUPINFO*)&si, &pi);
 
    //
    // cleanup
    //
    ::CloseHandle(hProcess);
    ::DeleteProcThreadAttributeList(attributes);
 
    return created;
}

Source code taken from https://scorpiosoftware.net/2021/01/10/parent-process-vs-creator-process/

Coconut
  • 2,024
  • 18
  • 25