Question

I have a application (.NET console app) written in C# that I run on a server. From time to time (about 2 times a week) the application crashes, this might for instance be caused by the network going down or something like that, but that's not important, what I want however, is that when the application crash I want it to simply silently restart. I can't rewrite the application to do this as I don't have the source, and I would like a simple solution to this, so I tried to create a bat file like this:

:start
@BotR.TestR.exe
echo sleeping
@ping 123.45.67.89 -n 1 -w %1000 > nul
goto start

However, whenever the application (BotR.TestR.exe) crashes, it pops up with a popup-window telling that the application crashed, witch stops it from continuing and thus stops it from restarting. Is there any simple way I can solve this?

Was it helpful?

Solution

I'm not sure this is the best way, but you can rewrite the application using Mono Cecil to do what you want like this:

ModuleDefinition module = ModuleDefinition.ReadModule(fileName);

var entryPoint = module.EntryPoint.Body;

var corlib = module.TypeSystem.Corlib;

var exceptionTypeReference = new TypeReference(
    "System", "Exception", null, corlib, false);
exceptionTypeReference = module.Import(exceptionTypeReference);

var entryPointIL = entryPoint.GetILProcessor();

var objectTypeReference = new TypeReference(
    "System", "Object", null, corlib, false);
objectTypeReference = module.Import(objectTypeReference);

var writeLineMethod =
    new MethodReference(
        "WriteLine",
        new TypeReference("System", "Void", null, corlib, true),
        new TypeReference("System", "Console", null, corlib, false))
    { Parameters = { new ParameterDefinition(objectTypeReference) } };
writeLineMethod = module.Import(writeLineMethod);

var callWriteLine = entryPointIL.Create(OpCodes.Call, writeLineMethod);
entryPointIL.Append(callWriteLine);

entryPointIL.Emit(OpCodes.Br, entryPoint.Instructions.First());

var exceptionHandler = new ExceptionHandler(ExceptionHandlerType.Catch)
                        {
                            CatchType = exceptionTypeReference,
                            TryStart = entryPoint.Instructions.First(),
                            TryEnd = callWriteLine,
                            HandlerStart = callWriteLine,
                            HandlerEnd = entryPoint.Instructions.Last()
                        };
entryPoint.ExceptionHandlers.Add(exceptionHandler);

module.Write(fileName);

What this code does is to take the entry point of the application (usually the Main() method) and rewrite it from this:

static void Main()
{
    // some code
}

into this:

static void Main()
{
    while (true)
    {
        try
        {
            // some code
        }
        catch (Exception exception)
        {
            Console.WriteLine(exception);
        }
    }
}

EDIT:

If the Main() method and the contain class are public, there is an easier way: create an application that has the other one as a reference and runs its Main(). Something like this:

class Program
{
    void Main()
    {
        while (true)
        {
            try
            {
                OtherApplication.Program.Main();
            }
            catch (Exception exception)
            {
                Console.WriteLine(exception);
            }
        }
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top