65.9K
CodeProject 正在变化。 阅读更多。
Home

执行程序 n 秒

starIconstarIconstarIconstarIconemptyStarIcon

4.00/5 (3投票s)

2009 年 4 月 29 日

CPOL

1分钟阅读

viewsIcon

34399

downloadIcon

182

启动一个程序,执行 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 - 原始版本
© . All rights reserved.