我正在开发一个应用程序,其中进程A的多个实例依赖于进程的单个实例B.这个想法是进程A的一个实例启动进程B以便所有实例A可以使用它。 A的实例托管在第三方进程中,并且可以在不可预测的时间点拆除(通过终止进程树)。因此,过程B不是过程A的任何实例的子项是至关重要的。
我尝试使用PInvoke调用CreateProcess,在创建标志中指定DetachedProcess(0x08),但这不起作用(请参阅下面的代码)。
[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);
}
我还阅读了How to create a process that is not a child of it's creating process?上的文章,该文章建议使用临时流程来启动新流程,但我并不热衷于这种方法,因为它会使同步复杂化,确保只有一个实例进程B已启动。
有谁知道更好的方法来实现这个目标?
答案 0 :(得分:4)
您可以尝试使用ManagementClass
启动流程并传递一些CreateFlags
,更具体地说,传递DETACHED_PROCESS
标记。 (您需要参考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();
}
至少在我的机器上,记事本不被视为我的控制台测试应用程序的子进程。