Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/273.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 创建一个新流程';它不是创建过程的子级_C#_Windows_Createprocess - Fatal编程技术网

C# 创建一个新流程';它不是创建过程的子级

C# 创建一个新流程';它不是创建过程的子级,c#,windows,createprocess,C#,Windows,Createprocess,我正在开发一个应用程序,其中一个流程的多个实例a依赖于一个流程的单个实例B。其思想是流程a的一个实例启动流程B,以便a的所有实例都可以使用它。的实例托管在第三方进程中,可以在不可预知的时间点上拆除(通过终止进程树)。因此,至关重要的是,进程B不是进程a的任何实例的子进程 我曾尝试使用PInvoke调用CreateProcess,在创建标志中指定DetachedProcess(0x08),但这不起作用(请参见下面的代码) 我还阅读了上的文章,其中建议使用一个临时流程来启动新流程,但我不喜欢这种方法

我正在开发一个应用程序,其中一个流程的多个实例a依赖于一个流程的单个实例B。其思想是流程a的一个实例启动流程B,以便a的所有实例都可以使用它。的实例托管在第三方进程中,可以在不可预知的时间点上拆除(通过终止进程树)。因此,至关重要的是,进程B不是进程a的任何实例的子进程

我曾尝试使用PInvoke调用CreateProcess,在创建标志中指定DetachedProcess(0x08),但这不起作用(请参见下面的代码)

我还阅读了上的文章,其中建议使用一个临时流程来启动新流程,但我不喜欢这种方法,因为它会使同步变得复杂,从而确保只启动流程B的一个实例

有人知道实现这一点的更好方法吗?

您可以尝试使用启动流程并传递一些,更具体地说,传递
分离的\u流程
标志。(您需要参考
System.Management

至少在我的机器上,记事本不被视为我的控制台测试应用程序的子进程。

您可以尝试使用启动进程并传递一些,更具体地说,传递
分离的\u进程
标志。(您需要参考
System.Management


至少在我的机器上,记事本不被视为我的控制台测试应用程序的子进程。

嗨,Jensen,谢谢你的回答。我曾考虑过使用WMI,但希望有人知道使用CreateProcess或类似工具的更简单方法。按照您的建议使用ManagementClass实际上将新进程的创建推迟到WMI。结果是新进程是wmiprvse.exe的子进程,而不是创建进程。DETACHED_进程标志对该结果没有影响。与PInvoke/CreateProcess中的等效标志一样,它的使用实际上会导致新流程在没有控制台的情况下进行初始化;它不控制新流程的父级状态。我想补充一点,您的建议无疑会解决我的问题,因为通过打破流程A和流程B实例之间的父子关系,杀死流程A实例的流程树不会杀死流程B。这正是我需要的!此解决方案解决了父子关系问题,允许用户从任务管理器结束流程树,以结束所有子流程。这样,就无法从父进程结束子进程,反之亦然(显然)嗨,Jensen,谢谢你的回答。我曾考虑过使用WMI,但希望有人知道使用CreateProcess或类似工具的更简单方法。按照您的建议使用ManagementClass实际上将新进程的创建推迟到WMI。结果是新进程是wmiprvse.exe的子进程,而不是创建进程。DETACHED_进程标志对该结果没有影响。与PInvoke/CreateProcess中的等效标志一样,它的使用实际上会导致新流程在没有控制台的情况下进行初始化;它不控制新流程的父级状态。我想补充一点,您的建议无疑会解决我的问题,因为通过打破流程A和流程B实例之间的父子关系,杀死流程A实例的流程树不会杀死流程B。这正是我需要的!此解决方案解决了父子关系问题,允许用户从任务管理器结束流程树,以结束所有子流程。这样,就无法从父进程结束子进程,反之亦然(显然)
[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);
}
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();
}