Обработка исключения, созданного внутри dll

Я работаю над проектом для школы, в который загружается dll.

Загруженная dll является мостом между моей программой и Twincat System Manager, который образует мост между компьютером и ПЛК через локальную сеть.

Мне нужно прочитать переменные через всю эту цепочку от ПЛК до моей программы.

Вот как я это делаю:

Public Function adsReadReal(ByVal Variabelenaam As String) As Single
    Dim ds = New TwinCAT.Ads.AdsStream(4 * 8) ' new data stream
    Dim br = New System.IO.BinaryReader(ds) 'new binary
    Dim hVar = New Integer
    Try
        ConState(1) 
        tcclient = New TcAdsClient
        ConState(2)
        tcclient.Connect(Form1.amsAdress, 801) 'connects the tcclient to the PLC
        hVar = tcclient.CreateVariableHandle(Variabelenaam) 'creats a handle for the variable
        tcclient.Read(hVar, ds) 'read it
        ConState(5)
        Return br.ReadSingle() 'convert it from binary to readable for vb
    Catch ex As Exception
        ConState(0)
        PrintEx(ex) 'print out the exception
    finally
        tcclient.Dispose() 'make the object stop being used to prevent a lingering connection
    End Try
    Return False
End Function

Теперь программа загружает dll с именем TwinCAT.ADS.dll в начале модуля подключения. Если системный менеджер Twincat работает, программа завершается нормально, но когда это не так, она падает и выдает мне эту ошибку:

Исключение System.DllNotFoundException не обработано
Message="Канал DLL tcadsdll.dll не загружен: Не загружен модуль запуска. (Отображение HRESULT: 0x8007007E)"
Source="TwinCAT.Ads"
TypeName=""
StackTrace:
bij TwinCAT.Ads.Internal.TcAdsDllWrapper.TcAdsDll.AdsAmsUnRegisterRouterNotification()
bij TwinCAT.Ads.Internal.TcAdsDllWrapper.AmsUnRegisterRouterNotification(Boolean throwAdsException)
bij TwinCAT.Ads.Internal.TcLocal .Dispose(логическое удаление)
bij TwinCAT.Ads.Internal.TcLocalSystem.Finalize()

что примерно переводится как:

Не удается загрузить DLL tcadsdll.dll: не удается найти данный модуль. (Исключение в HRESULT: 0x8007007E)

Это не dll, который я импортировал, поэтому он должен быть из TwinCAT.ADS.dll

Как я могу помешать программе выдать мне эту ошибку и вместо этого мирно закрыть программу? Я попытался поймать все исключения каждой возможной операции, связанной с dll.

Также источник находится на Bitbucket. Я сделаю это общедоступным по запросу.

Несколько ссылок на официальный, но довольно громоздкий сайт Beckhoff:

http://infosys.beckhoff.com/espanol.php?content=../content/1034/tcquickstart/html/tcquickstart_samplevisualbasicnet.htm&id=10449

Редактировать: Очевидно, использование tcclient.dispose() вызывает ошибку, так как выражение finnaly использовалось вместо блока try сразу после него.

Изменить: В настоящее время это перехватывает исключение, но не обрабатывает его.

Dim currentDomain As AppDomain = AppDomain.CurrentDomain
AddHandler currentDomain.UnhandledException, AddressOf MyHandler
Dim tick As Byte = 0

Sub MyHandler(sender As Object, args As UnhandledExceptionEventArgs)
   Dim ex As Exception = DirectCast(args.ExceptionObject, Exception)
   MsgBox("exception tick" & Str(tick))
   tick = tick + 1
   PrintEx(ex)
End Sub

Редактировать: исключение не перехватывается должным образом, потому что в vs2008 происходит несколько ошибок, но галочка появляется после того, как я нажимаю F5 (продолжить)

Когда программа запускается напрямую, я вижу только 1 тик. Потом винда выдает ошибку.


person Lander Ghekiere    schedule 17.05.2012    source источник
comment
Просто примечание: добавьте предложение finally после оператора catch. Это гарантирует, что удаление произойдет, даже если программа аварийно закроется.   -  person JonH    schedule 17.05.2012
comment
Мне кажется, что вам не хватает зависимости импортированной библиотеки.   -  person dwerner    schedule 17.05.2012
comment
@dwerner Не происходит, когда Twincat работает так, как должен.   -  person Lander Ghekiere    schedule 17.05.2012
comment
Сборки могут быть загружены во время выполнения. Я не знаю, как вы предотвратите попытку загрузки кода, который не принадлежит вам.   -  person dwerner    schedule 17.05.2012
comment
@dwerner можно ли увидеть запущенные процессы без повышения прав? Если это так, я могу запретить программе запускать любой из тех объектов, которым требуется dll, и закрыть все это.   -  person Lander Ghekiere    schedule 17.05.2012


Ответы (1)


Вы пробовали обработчик необработанных исключений?

Dim currentDomain As AppDomain = AppDomain.CurrentDomain
AddHandler currentDomain.UnhandledException, AddressOf MyHandler

Sub MyHandler(sender As Object, args As UnhandledExceptionEventArgs)
   Dim e As Exception = DirectCast(args.ExceptionObject, Exception)
   Console.WriteLine("MyHandler caught : " + e.Message)
End Sub
person Jimmy D    schedule 17.05.2012
comment
AddHandler здесь не распознается. Выдает: Синтаксическая ошибка. - person Lander Ghekiere; 17.05.2012
comment
Убедитесь, что вы разместили его в правильном месте: msdn. microsoft.com/en-us/library/ - person Jimmy D; 17.05.2012
comment
Ваша ошибка должна исходить не из того места, где вы определили этот обработчик, иначе она будет обработана. - person Jimmy D; 18.05.2012
comment
Хорошо, я ловлю исключение после некоторых исправлений. Но как я могу это решить? - person Lander Ghekiere; 18.05.2012
comment
Очевидно, DLL, которую вы вызываете, ищет другой файл. Так что единственный способ решить вашу проблему — обратиться к разработчику DLL. Но если мой ответ помог, пожалуйста, примите его :) - person Jimmy D; 18.05.2012
comment
мое решение: просто уведомить пользователя и завершить программу при возникновении ошибки. Тем не менее, помог выделить исключение. Спасибо! - person Lander Ghekiere; 18.05.2012