Creating a new process that's not a child of the creating process

雨燕双飞 提交于 2019-12-20 04:23:05

问题


I am developing an application in which a number of instances of a process, A, depend on a single instance of a process, B. The idea is that one of the instances of process A starts process B so that all the instances of A can use it. The instances of A are hosted in a 3rd party process and can be torn down (by killing the process tree) at unpredictable points in time. It is therefore vital that process B is not a child of any instance of process A.

I have tried to do this using PInvoke to call CreateProcess, specifying DetachedProcess (0x08) in the creation flags, but this did not work (please see code below).

[DllImport("kernel32.dll")]
private static extern bool CreateProcess(string lpApplicationName, string lpCommandLine, IntPtr lpProcessAttributes, IntPtr lpThreadAttributes, bool bInheritHandles, uint dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, [In] ref StartupInfo lpStartupInfo, out ProcessInformation lpProcessInformation);


public Process LaunchProcess(Path executablePath, string args)
{
    StartupInfo sInfo = new StartupInfo();

    const uint creationFlags = (uint)(CreationFlags.CreateNoWindow | CreationFlags.DetachedProcess);

    ProcessInformation pInfo;
    bool success = CreateProcess(executablePath.ToString(), args, IntPtr.Zero, IntPtr.Zero, false, creationFlags, IntPtr.Zero, executablePath.GetFolderPath().ToString(), ref sInfo, out pInfo);

    if (!success)
    {
        throw new Win32Exception();
    }

    return Process.GetProcessById(pInfo.dwProcessId);
}

I have also read the article at How to create a process that is not a child of it's creating process?, which suggested using an interim process to start the new process, but I am not keen on this approach as it would complicate the synchronisation around ensuring that only a single instance of process B is started.

Does anyone know of a better way of achieving this?


回答1:


You can try to use the ManagementClass to launch a process and pass some CreateFlags, more specifically, the DETACHED_PROCESS flag. (You'll need to reference System.Management.)

private static void Main()
{
    using (var managementClass = new ManagementClass("Win32_Process"))
    {
        var processInfo = new ManagementClass("Win32_ProcessStartup");
        processInfo.Properties["CreateFlags"].Value = 0x00000008;

        var inParameters = managementClass.GetMethodParameters("Create");
        inParameters["CommandLine"] = "notepad.exe";
        inParameters["ProcessStartupInformation"] = processInfo;

        var result = managementClass.InvokeMethod("Create", inParameters, null);
        if ((result != null) && ((uint)result.Properties["ReturnValue"].Value != 0))
        {
            Console.WriteLine("Process ID: {0}", result.Properties["ProcessId"].Value);
        }
    }

    Console.ReadKey();
}

At least on my machine notepad is not considered a child process of my console test application.



来源:https://stackoverflow.com/questions/12068647/creating-a-new-process-thats-not-a-child-of-the-creating-process

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!