假设我有一个只产生一个子进程的进程.现在,当父进程因任何原因(正常或异常,通过kill,^ C,断言失败或其他任何原因)退出时,我希望子进程死掉.如何正确地做到这一点?
stackoverflow上的一些类似问题:
关于Windows的 stackoverflow的一些类似问题:
我正在寻找很多方法来获取.NET中的父进程,但只找到了P/Invoke方式.
我以编程方式启动Internet Explorer,代码如下所示:
ProcessStartInfo startInfo = new ProcessStartInfo("iexplore.exe");
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.Arguments = "http://www.google.com";
Process ieProcess = Process.Start(startInfo);
Run Code Online (Sandbox Code Playgroud)
这将生成Windows任务管理器中可见的2个进程.然后,我尝试用以下方法终止进程:
ieProcess.Kill();
Run Code Online (Sandbox Code Playgroud)
这导致任务管理器中的一个进程被关闭,另一个进程仍然存在.我尝试检查任何具有子进程的属性,但没有找到.我怎么能杀死其他进程呢?更一般地说,如何杀死与Process.Start开始的进程相关的所有进程?
我正在努力拼凑一个pinvoke'ing CreateJobObject和SetInformationJobObject的工作示例.通过各种谷歌搜索(包括俄罗斯和中国的帖子!)我拼凑了以下代码.我认为JOBOBJECT_BASIC_LIMIT_INFORMATION的定义基于平台(32/64位)而变化.CreateJobObject/AssignProcessToJobObject 似乎工作.SetInformationJobObject失败 - 错误24或87.
Process myProcess // POPULATED SOMEWHERE ELSE
// Create Job & assign this process and another process to the job
IntPtr jobHandle = CreateJobObject( null , null );
AssignProcessToJobObject( jobHandle , myProcess.Handle );
AssignProcessToJobObject( jobHandle , Process.GetCurrentProcess().Handle );
// Ensure that killing one process kills the others
JOBOBJECT_BASIC_LIMIT_INFORMATION limits = new JOBOBJECT_BASIC_LIMIT_INFORMATION();
limits.LimitFlags = (short)LimitFlags.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
IntPtr pointerToJobLimitInfo = Marshal.AllocHGlobal( Marshal.SizeOf( limits ) );
Marshal.StructureToPtr( limits , pointerToJobLimitInfo , false );
SetInformationJobObject( job , JOBOBJECTINFOCLASS.JobObjectBasicLimitInformation , …Run Code Online (Sandbox Code Playgroud) 当我从Visual Studio启动我的进程时,它总是在作业对象中创建.我想知道如何关闭此行为.有任何想法吗?
我希望它是在要调试的作业对象中创建的.我想将我的程序放在不同的作业对象中.
这不是托管过程.我在谈论一个工作对象.这是一个非托管的C++应用程序.
任务:如果父进程终止,则自动终止所有子进程.父进程不仅可以以正确的方式终止,还可以通过在ProcessExplorer中进行终止来终止.我该怎么做?
在С主题建议中使用Job对象的类似问题.如何在C#中使用它而不导出外部DLL?
我试着使用Job Objects.但是这段代码不能正常工作:
var job = PInvoke.CreateJobObject(null, null);
var jobli = new PInvoke.JOBOBJECT_BASIC_LIMIT_INFORMATION();
jobli.LimitFlags = PInvoke.LimitFlags.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE
| PInvoke.LimitFlags.JOB_OBJECT_LIMIT_PRIORITY_CLASS
| PInvoke.LimitFlags.JOB_OBJECT_LIMIT_JOB_TIME
| PInvoke.LimitFlags.JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION
| PInvoke.LimitFlags.JOB_OBJECT_LIMIT_JOB_MEMORY;
var res = PInvoke.SetInformationJobObject(job, PInvoke.JOBOBJECTINFOCLASS.JobObjectBasicLimitInformation, jobli, 48);
if (!res)
{
int b = PInvoke.GetLastError();
Console.WriteLine("Error " + b);
}
var Prc = Process.Start(...);
PInvoke.AssignProcessToJobObject(job, Prc.Handle);
Run Code Online (Sandbox Code Playgroud)
PInvoke.SetInformationJobObject返回错误.GetLastError返回错误24.但是,PInvoke.AssignProcessToJobObject工作,子进程添加到作业队列(我可以在ProcessExplorer中看到它).但是,因为PInvoke.SetInformationJobObject不起作用 - 当我杀死父节点时,生成的进程保持活动状态.
我在这段代码中有什么不正确的地方?
有没有办法调用CreateProcess,以便杀死父进程自动杀死子进程?
也许使用Create Process Flags?
编辑
解决方案是创建作业对象,将父级和子级放在作业对象中.当父母被杀后,孩子被杀.我从这里得到了代码:
当父进程被杀死时杀死子进程
记下@wilx关于继承句柄的注释.
我无法使用Process.Kill().我想我一定是在误解它是如何运作的.这是我的测试功能.我开始一个长时间运行的进程(ping -t),然后在五秒后终止它.
我可以看到ping进程显示,但程序结束后进程仍然存在.我必须手动杀死它.
Console.WriteLine("Total number of ping processes is {0}", Process.GetProcessesByName("ping").Length);
ProcessStartInfo startInfo = new ProcessStartInfo("cmd.exe");
Process process = new Process();
startInfo.CreateNoWindow = true;
startInfo.UseShellExecute = false;
startInfo.Arguments = "/c ping -t 8.8.8.8";
Console.WriteLine("Staring ping process");
process.StartInfo = startInfo;
process.Start();
Thread.Sleep(5000);
Console.WriteLine("Total number of ping processes is {0}", Process.GetProcessesByName("ping").Length);
Thread.Sleep(5000);
Console.WriteLine("Killing ping process");
process.Kill();
Thread.Sleep(5000);
Console.WriteLine("Total number of ping processes is {0}", Process.GetProcessesByName("ping").Length);
Run Code Online (Sandbox Code Playgroud)
我在这做错了什么?
我对C#很新,所以我的问题可能听起来很荒谬.我正在开发一个有时需要运行ffmpeg的应用程序.正如您所猜测的,当主机应用程序关闭时,必须终止此ffmpeg进程.我使用这样的代码来完成这项任务:
AppDomain.CurrentDomain.ProcessExit += new EventHandler(OnProcessExit);
private void OnProcessExit(object sender, EventArgs e)
{
proc.Kill();
}
Run Code Online (Sandbox Code Playgroud)
当应用程序正确关闭时(通过它的界面或使用Taskman - Applications),这样可以正常工作.问题是OnProcessExit事件不会触发,如果程序的进程被杀死(使用Taskman - Processes).据我所知,杀戮过程和关闭程序操作在低级别上并不相同,但我想,杀戮过程是一个命令,它可以用C#工具处理.那么,在这种情况下关闭子进程是否可能?
我有一个很好的老式 Windows 服务(继承自 System.ServiceProcess.ServiceBase),我向其中添加了一个组件(实现 IComponent),但是如果我从任务管理器关闭 exe,this.components.Add(new MyStuff());
MyStuff就不会运行。Disposable()
可能的嫌疑人:
出于测试目的,我开始我的服务
var service = new MyService();
service.Run();
Thread.Wait(Timeout.Infinite);
而不是ServiceBase.Run(new []{new MyService()});这可能是问题所在?
请帮忙!
附加信息:我正在尝试使用 Process.Start(...) 关闭我从服务中启动的其他 exe,所以如果有办法让它们自动关闭(子进程?),那也可以。
我有一个启动exe进程的powershell脚本.我有一个任务计划在计算机空闲时运行这个powershell脚本,我设置它在它没有空闲时停止它.
问题是任务计划没有杀死启动的exe进程,我假设它只是试图杀死PowerShell进程.
当从任务调度程序启动时,我似乎无法找到一种方法将启动的exe作为powershell.exe的子进程
我已经尝试使用invoke-expression,start-proces启动进程,我也试图通过管道输出out-null,wait-process等等.当从任务调度程序启动ps1时,似乎没有任何工作.
有没有办法实现这个目标?
谢谢
我有一个控制台应用程序的主线程,以这种方式运行很少的外部进程
private static MyExternalProcess p1;
private static MyExternalProcess p2;
private static MyExternalProcess p3;
public void Main() {
p1 = new MyExternalProcess();
p2 = new MyExternalProcess();
p3 = new MyExternalProcess();
p1.startProcess();
p2.startProcess();
p3.startProcess();
}
public static void killEveryoneOnExit() {
p1.kill();
p2.kill();
p3.kill();
}
class MyExternalProcess {
private Process p;
...
public void startProces() {
// do some stuff
PlayerProcess = new Process();
....
PlayerProcess.Start();
// do some stuff
}
public void kill() {
// do some stuff
p.Kill();
}
}
Run Code Online (Sandbox Code Playgroud)
我需要做的是:当主线程被中断时(退出按钮或ctrl …