Есть 1С-addin, писанный на шарпе.
Все замечательно работает кроме одного момента — хочу перехватить .NET-исключение и передать его в 1С для того, чтобы остановить выполнение 1С-ного модуля ну и отобразить исключение в окне сообщений. Для этого использую IErrorLog, который прекрасно работает в неуправляемых addin'ах:
[Guid("3127CA40-446E-11CE-8135-00AA004BB851")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IErrorLog
{
void AddError(String pszPropName, System.Runtime.InteropServices.ComTypes.EXCEPINFO pExepInfo);
}
public void Init(Object connection)
{
Connection = connection;
ErrorLog = (IErrorLog)Connection;
}
protected void PostException(Exception ex)
{
if (ErrorLog == null)
return;
var info = new EXCEPINFO
{
wCode = 1006,
bstrDescription = String.Format(_addinError, ex.GetType(), ex.Message, ex.StackTrace),
bstrSource = AddInName,
scode = 1
};
ErrorLog.AddError("", info);
}
На вызове ErrorLog.AddError получаю AccessViolation, 1С это спокойно проглатывает и радостно работает дальше.
Более того, если просто выбросить в .NET-коде необработанное исключение, 1С пофигу, хотя даже б-гмерзкий Delphi в этом случае падает с OLE-шным исключением.
Проверял на версиях платформы 7.7 и 8.2.
Перепробовал все распостранненые в интернетах примеры 1С-ных addin'ов, определений IErrorLog и структуры EXCEPINFO. Результат один и тот же.
На GDN'не нашелся один счастливец, столкнувшийся с этой проблемой, решивший ее и запостивший исходник с решением на сервер, откуда его уже благополучно удалили.
[PreserveSig]
int AddError([In, MarshalAs(UnmanagedType.LPWStr)] string pszPropName,
[In, MarshalAs(UnmanagedType.Struct)] System.Runtime.InteropServices.ComTypes.EXCEPINFO pExcepInfo);
Эти парни, IMHO, круче всех. У них AddError вместо void стал int.
Падаем с AV.
4) Ну и наконец, раскрутившие себя в поисковиках (запрос "внешнаяя компонента для 1с на C#") и загадившие рунет (т.к. по их шаблону пишут компоненты много страждущих, видимо, потому что первый находится в поиске) оригиналы из mista.ru:
[Guid("3127CA40-446E-11CE-8135-00AA004BB851"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IErrorLog
{
void AddError(string pszPropName, ExcepInfo pExepInfo);
}
//----------------------------------------------------------
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode, Pack=8)]
public struct ExcepInfo
{
public short wCode;
public short wReserved;
[MarshalAs(UnmanagedType.BStr)] public string bstrSource;
[MarshalAs(UnmanagedType.BStr)] public string bstrDescription;
[MarshalAs(UnmanagedType.BStr)] public string bstrHelpFile;
public int dwHelpContext;
public System.IntPtr pvReserved;
public System.IntPtr pfnDereffered;
public int scode;
}
Даже не поленились написать свое определение ExcepInfo. Результат — Падаем с AV.
Я понимаю, что вопрос "на кой черт выкладывать нерабочие исходники" в данном случае — риторический, но тем не менее... cтатья раскручена в поисковиках . Кстати, я не VB-шник, любопытно, вот этот их код работает (из этой же статьи):
Dim ei As ExcepInfo = New ExcepInfo()
ei.wCode = 1004 '//Вид пиктограммы
ei.scode = 1 '//Генерируем ошибку времени исполнения
ei.bstrDescription = s '//Сообщение
ei.bstrSource = c_AddinName
V7Data.ErrorLog.AddError(c_AddinName, ei)
Напоминаю, что речь идет о стандартном для COM интерфейсе. И все эти определения используют один и тот же IID.
Ппц.
Здравствуйте, HowardLovekraft, Вы писали:
HL>Даже не поленились написать свое определение ExcepInfo. Результат — Падаем с AV. HL>Я понимаю, что вопрос "на кой черт выкладывать нерабочие исходники" в данном случае — риторический, но тем не менее... cтатья раскручена в поисковиках . Кстати, я не VB-шник, любопытно, вот этот их код работает (из этой же статьи):
Я тоже, но в VB как кстати и в 1С параметры передаются по ссылке. В Delphi кстати для вызовов методов через вариант параметры тоже передаются по ссылке. HL>
HL> Dim ei As ExcepInfo = New ExcepInfo()
HL> ei.wCode = 1004 '//Вид пиктограммы
HL> ei.scode = 1 '//Генерируем ошибку времени исполнения
HL> ei.bstrDescription = s '//Сообщение
HL> ei.bstrSource = c_AddinName
HL> V7Data.ErrorLog.AddError(c_AddinName, ei)
HL>
HL>Напоминаю, что речь идет о стандартном для COM интерфейсе. И все эти определения используют один и тот же IID. HL>Ппц.
и солнце б утром не вставало, когда бы не было меня
<Guid("3127CA40-446E-11CE-8135-00AA004BB851"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)> _
Public Interface IErrorLog
Sub AddError(ByVal pszPropName As String, ByRef pExepInfo As ExcepInfo)
End Interface
'----------------------------------------------------------
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode, Pack:=8)> _
Public Structure ExcepInfo
Public wCode As Short
Public wReserved As Short
<MarshalAs(UnmanagedType.BStr)> Public bstrSource As String
<MarshalAs(UnmanagedType.BStr)> Public bstrDescription As String
<MarshalAs(UnmanagedType.BStr)> Public bstrHelpFile As String
Public dwHelpContext As Integer
Public pvReserved As IntPtr
Public pfnDereffered As IntPtr
Public scode As Integer
End Structure
и солнце б утром не вставало, когда бы не было меня