创建一个不是创建进程的子进程的新进程 [英] Creating a new process that's not a child of the creating process
问题描述
我正在开发一个应用程序,其中进程 A 的多个实例依赖于进程 B 的单个实例.这个想法是进程 A 的一个实例启动进程 B,以便所有实例的A可以使用它.A 的实例托管在第 3 方进程中,并且可以在不可预测的时间点被拆除(通过终止进程树).因此,进程 B 不是进程 A 的任何实例的子进程至关重要.
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.
我尝试使用 PInvoke 调用 CreateProcess,在创建标志中指定 DetachedProcess (0x08),但这不起作用(请参阅下面的代码).
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);
}
我还阅读了 如何创建一个不是它正在创建的进程的子进程的进程?,它建议使用一个临时进程来启动新进程,但我并不热衷于这种方法,因为它会复杂化围绕确保仅启动进程 B 的单个实例的同步.
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?
推荐答案
您可以尝试使用 ManagementClass
启动进程并传递一些 CreateFlags
,更具体地说,DETACHED_PROCESS代码> 标志.(您需要参考
System.Management
.)
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.
这篇关于创建一个不是创建进程的子进程的新进程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!