Приложение Handeling вылетает в bat-файле - PullRequest
1 голос
/ 03 ноября 2011

У меня есть приложение (консольное приложение .NET), написанное на C #, которое я запускаю на сервере.Время от времени (примерно 2 раза в неделю) происходит сбой приложения, например, это может быть вызвано отключением сети или чем-то подобным, но это не важно, однако я хочу, чтобы при сбое приложения я хотелпросто тихо перезапустить.Я не могу переписать приложение, чтобы сделать это, поскольку у меня нет исходного кода, и я хотел бы простое решение этого, поэтому я попытался создать файл bat следующим образом:

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

Однаковсякий раз, когда происходит сбой приложения (BotR.TestR.exe), появляется всплывающее окно с сообщением о сбое приложения, которое останавливает его продолжение и, таким образом, останавливает его перезапуск.Есть ли какой-нибудь простой способ решить эту проблему?

1 Ответ

1 голос
/ 03 ноября 2011

Я не уверен, что это лучший способ, но вы можете переписать приложение, используя Mono Cecil , чтобы сделать то, что вы хотите, как это:

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);

Что этот код делает, так это берет точку входа приложения (обычно метод Main()) и переписывает ее из этого:

static void Main()
{
    // some code
}

в это:

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

EDIT:

Если метод Main() и класс содержимого являются общедоступными, существует более простой способ: создать приложение, которое использует другое в качестве ссылки и запускает его Main(). Примерно так:

class Program
{
    void Main()
    {
        while (true)
        {
            try
            {
                OtherApplication.Program.Main();
            }
            catch (Exception exception)
            {
                Console.WriteLine(exception);
            }
        }
    }
}
...