Click here to Skip to main content
15,885,767 members
Articles / Desktop Programming / Win32

Execute a Program for n Seconds

Rate me:
Please Sign up or sign in to vote.
4.00/5 (3 votes)
29 Apr 2009CPOL1 min read 33.1K   167   17   16
Start a program, execute for n seconds, then kill it

Introduction

I have a script which runs many sub programs, each sub program fetches a web page, filters its contents and outputs frequently (the output are placed in stdout). It usually works fine, although sometimes it hangs. It is not good because one sub program hangs, the whole script hangs. When it hangs, I always start the Process Explorer to kill this sub program, then the script keeps running. I wanted the script to kill the dead sub program after 30 seconds automatically, so I wrote this program.

Sorry my English is bad.

Background

None.

Using the Code

This is a console application. This program's command line format is:

exec4.exe seconds commandline arguments        

For example, the following command will run "dir /s c:\", wait for 10 seconds and kill.

exec4.exe 10 cmd.exe /c dir /s c:\

You can get exec4.exe. Please download and extract Exec4.zip, and compile:

csc exec4.cs

The source code is listed below:

C#
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); 
                } 
        }
}

Points of Interest

This program uses WinExec Windows API to launch the sub program. It uses Process.GetProcessesByName() function to get related programs and kill the pending sub program as necessary.

Summary

This article describes an approach to start a sub program and stop it automatically. It doesn't kill the sub program's process tree. It introduces a method to kill the pending sub program without any warrant. I hope it is useful to you. Happy Labor's Day!

History

  • 30.04.09 - Original version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Taiwan Taiwan
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionUse a Timer? Pin
pinx5-May-09 0:25
pinx5-May-09 0:25 
AnswerRe: Use a Timer? Pin
Linccg5-May-09 1:54
Linccg5-May-09 1:54 
GeneralRe: Use a Timer? Pin
Fiwel5-May-09 5:28
Fiwel5-May-09 5:28 
GeneralRe: Use a Timer? Pin
Linccg5-May-09 7:26
Linccg5-May-09 7:26 
GeneralRe: Use a Timer? Pin
Fiwel5-May-09 7:35
Fiwel5-May-09 7:35 
GeneralRe: Use a Timer? Pin
Linccg5-May-09 7:53
Linccg5-May-09 7:53 
GeneralRe: Use a Timer? Pin
Fiwel5-May-09 7:42
Fiwel5-May-09 7:42 
GeneralRe: Use a Timer? Pin
Linccg5-May-09 9:06
Linccg5-May-09 9:06 
It's the reason: simple. The WinExec() 'parses' command line well and 'redirects' the stdout and stderr easily. Smile | :)
GeneralRe: Use a Timer? Pin
Fiwel5-May-09 9:18
Fiwel5-May-09 9:18 
GeneralRe: Use a Timer? Pin
Linccg5-May-09 10:36
Linccg5-May-09 10:36 
Generalfetching web page Pin
TranQuangDao1-May-09 7:49
professionalTranQuangDao1-May-09 7:49 
GeneralRe: fetching web page Pin
Linccg1-May-09 12:12
Linccg1-May-09 12:12 
GeneralRe: fetching web page Pin
TranQuangDao3-May-09 6:02
professionalTranQuangDao3-May-09 6:02 
GeneralBug fixed Pin
Linccg29-Apr-09 16:16
Linccg29-Apr-09 16:16 
GeneralMy way Pin
PIEBALDconsult29-Apr-09 13:57
mvePIEBALDconsult29-Apr-09 13:57 
GeneralRe: My way Pin
Linccg29-Apr-09 15:26
Linccg29-Apr-09 15:26 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.