Есть одна проблемка может ктонибуть подскажет как её решить.
В нашем текущем проекте есть один бэкэнд написанный на
C++ который иногда может красиво упасть по
AccessViolatioException.
И если такое исключение произошло то дальше этот сервис становится нерабочим. После долгих попыток решить эту проблему было решено написать воркэраунд, который будет запускать этот сервис в отдельном процессе и в случае его падения перезапускать процесс.
Проблема
IPC была легко решена с помощью
WCF. Но появилась новая проблема, если процесс падает, то появляется виндошное окошко мол процесс завершился (
Process has stopped working) и действия Закрыть приложение, Поискать решение online, Или оттдебажить программу. (К сожалению не знаю куда залить картинку). Но уверен что все много раз видили это сообщение.
Windows 7 x64 если что.
В результате основное приложение не получает сообщение о том что процесс упал и был закрыт, а значит он не может его перезапустить (так как для него процесс все ещё работает)
В этом собственно и вопрос как заставить процесс упасть тихо без всяких виндошных сообщений?
Немного по деталям реализации, VS 2010, .NET 4.0, Приложение обычное консольное.
Подписка на
AppDomain.CurrentDomain.UnhandledException ни к чему не привела, метод вызывает
А винда все равно выдает это сообщение о закрытии процесса.
Сейчас буду пробовать вариант с
Windows Application вместа
Console Application, потому что у класс
Application хотябы
Exit можно вызвать в случае
UnhandledException. Но есть подозрение что это мало поможет
Заранее спасибо если кто-то может поделиться хоть какой-то информацией по этому поводу.
Здравствуйте, _WerWolf_, Вы писали:
_WW>Есть одна проблемка может ктонибуть подскажет как её решить.
_WW>Заранее спасибо если кто-то может поделиться хоть какой-то информацией по этому поводу.
попробуйте вызвать метод Environment.Exit в обработчике необработанного исключения домена
Кроме того, может это поможет:
CLR via CSharp 3rd Edition
Note The CLR considers some exceptions thrown by native code as corrupted state exceptions
(CSEs) because they are usually the result of a bug in the CLR itself or in some native code for
which the managed developer has no control over . By default, the CLR will not let managed code
catch these exceptions and finally blocks will not execute . Here is the list of native Win32
exceptions that are considered CSEs:
EXCEPTION_ACCESS_VIOLATION EXCEPTION_STACK_OVERFLOW
EXCEPTION_ILLEGAL_INSTRUCTION EXCEPTION_IN_PAGE_ERROR
EXCEPTION_INVALID_DISPOSITION EXCEPTION_NONCONTINUABLE_EXCEPTION
EXCEPTION_PRIV_INSTRUCTION STATUS_UNWIND_CONSOLIDATE .
Individual managed methods can override the default and catch these exceptions by applying
the System.Runtime.ExceptionServices.HandleProcessCorruptedStateExceptionsAttribute
to the method . In addition, the method must have the System.Security.
SecurityCriticalAttribute applied to it . You can also override the default for an entire
process by setting the legacyCorruptedStateExceptionPolicy element in the application’s
Extensible Markup Language (XML) configuration file to true . The CLR converts most of these
to a System.Runtime.InteropServices.SEHException object except for EXCEPTION_
ACCESS_VIOLATION, which is converted to a System.AccessViolationException object, and
EXCEPTION_STACK_OVERFLOW, which is converted to a System.StackOverflowException
object .
Здравствуйте, _WerWolf_, Вы писали:
_WW>Есть одна проблемка может ктонибуть подскажет как её решить.
#include "stdafx.h"
#include "windows.h"
LONG WINAPI MyUnhandledExceptionFilter(
__in struct _EXCEPTION_POINTERS* ExceptionInfo
)
{
printf("Failed\n");
return EXCEPTION_EXECUTE_HANDLER;
}
int _tmain(int argc, _TCHAR* argv[])
{
SetErrorMode(SEM_NOGPFAULTERRORBOX);
SetUnhandledExceptionFilter(MyUnhandledExceptionFilter);
char* p = NULL;
*p = 0;
return 0;
}
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, _WerWolf_, Вы писали:
_WW>>Есть одна проблемка может ктонибуть подскажет как её решить.
PD>PD>#include "stdafx.h"
PD>#include "windows.h"
PD>LONG WINAPI MyUnhandledExceptionFilter(
PD> __in struct _EXCEPTION_POINTERS* ExceptionInfo
PD>)
PD>{
PD> printf("Failed\n");
PD> return EXCEPTION_EXECUTE_HANDLER;
PD>}
PD>int _tmain(int argc, _TCHAR* argv[])
PD>{
PD> SetErrorMode(SEM_NOGPFAULTERRORBOX);
PD> SetUnhandledExceptionFilter(MyUnhandledExceptionFilter);
PD> char* p = NULL;
PD> *p = 0;
PD> return 0;
PD>}
PD>
О спасибо, это решение даже лучше!
[Flags]
internal enum ErrorModes : uint
{
SystemDefault = 0x0,
SemFailCriticalErrors = 0x0001,
SemNoAlignmentFaultExcept = 0x0004,
SemNoGpFaultErrorBox = 0x0002,
SemNoOpenFileErrorBox = 0x8000
}
internal class SetErrorModeExtern
{
[DllImport("kernel32.dll")]
public static extern ErrorModes SetErrorMode(ErrorModes uMode);
}
Ну и соответственно в Main() первая строчка
private static int Main( string[] args )
{
SetErrorModeExtern.SetErrorMode( ErrorModes.SemNoGpFaultErrorBox );
Все красиво тихо закрывается. Супер!