执行程序 n 秒
启动一个程序,执行 n 秒,然后结束它
引言
我有一个脚本,它运行许多子程序,每个子程序都获取一个网页,过滤其内容并频繁输出(输出放置在 stdout
中)。它通常工作正常,但有时会卡住。一个子程序卡住,整个脚本就会卡住,这不太好。当它卡住时,我总是启动进程资源管理器来结束这个子程序,然后脚本继续运行。我希望脚本在 30 秒后自动结束死掉的子程序,所以我编写了这个程序。
抱歉我的英语不好。
背景
无。
Using the Code
这是一个控制台应用程序。该程序的命令行格式是
exec4.exe seconds commandline arguments
例如,以下命令将运行“dir /s c:\
”,等待 10 秒并结束程序。
exec4.exe 10 cmd.exe /c dir /s c:\
您可以获取 exec4.exe。请下载并解压缩 Exec4.zip,然后编译
csc exec4.cs
源代码如下所示
using System;
using System.Threading;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Collections.Generic;
class Exec4
{
[DllImport("kernel32.dll")]
public static extern int WinExec(string exeName, int operType);
public static void Main(string []args)
{
// args[0] seconds
// args[1..n] commandline
if (args.Length<1)
{
Console.WriteLine("Usage:");
Console.WriteLine("\tExec4.exe Seconds Commandline");
return;
}
else
{
// Check for arguments.
int Expires;
try
{
Expires = Convert.ToInt32(args[0]);
}
catch
{
Expires = -1;
}
if (Expires<=0)
{
Console.Error.Write("Seconds argument error: ");
Console.Error.WriteLine(args[0]);
return;
}
string cmdLine=args[1];
for (int i=2; i<args.Length; i++) cmdLine+=" "+args[i];
string AppName=args[1];
if (AppName.ToLower().EndsWith(".exe")) AppName=
AppName.Substring(0, AppName.Length-4);
List<int> ProcessIds=new List<int>();
foreach (Process aProcess in Process.GetProcessesByName
(AppName))
ProcessIds.Add(aProcess.Id);
int hr=WinExec(cmdLine,0);
if (hr<=31)
{
// Execute failed.
Console.Error.Write("SubProgram executes abnormally: ");
Console.Error.WriteLine(cmdLine);
return;
}
DateTime dtStart=DateTime.Now;
// Get the process id of the sub program.
int SubProgramProcessId=-1;
foreach (Process aProcess in Process.GetProcessesByName
(AppName))
if (-1==ProcessIds.IndexOf(aProcess.Id))
{
SubProgramProcessId=aProcess.Id;
break;
}
if (-1==SubProgramProcessId)
{
// We need SubProgramProcessId to stop sub program.
Console.Error.WriteLine("Cannot stop SubProgram!");
return;
}
while ((DateTime.Now - dtStart).TotalSeconds<Expires)
{
Thread.Sleep(100);
//Program end normally.
int found=0;
foreach (Process aProcess in Process.GetProcessesByName
(AppName))
if (SubProgramProcessId==aProcess.Id)
{
found=1;
break;
}
if (0==found) return;
}
//Program expired, kill it.
foreach (Process ExpiredProcess in Process.GetProcessesByName
(AppName))
if (SubProgramProcessId==ExpiredProcess.Id)
ExpiredProcess.Kill();
Console.Error.WriteLine("Expire!");
Environment.Exit(-1);
}
}
}
关注点
该程序使用 WinExec
Windows API 来启动子程序。它使用 Process.GetProcessesByName()
函数来获取相关程序并根据需要结束待处理的子程序。
摘要
本文描述了一种启动子程序并自动停止它方法。它不会结束子程序的进程树。它介绍了一种无需任何保证即可结束待处理子程序的方法。希望对您有所帮助。劳动节快乐!
历史
- 2009-04-30 - 原始版本