Ошибка при закрытии формы с ФТП-сессией.
Код принудительного завершения соединения:
ClientCloseFtp();
Close();
Обработка события закрытия формы:
Action = caFree;
Обработка запроса на закрытие формы
ftpMain->Disconnect();//Компонент TNMFTP
}
rasMain->HangUp();//Компонент осуществляющий дозвон
delete rasMain;
LogEvents("Çàâåðøåíèå ðàáîòû");//Функция логирования событий
Закрытие соединения:
{
if(ConnectSocketError)
ftpMain->Abort();
else ftpMain->Disconnect();
return true;
}
Ну вроде все.
Ты пробовал словить исключение, через TApplication.OnExeption? Хотя причину исключения это не исправляет, но хоть баг незаметен :)
Чел, в программе которого загружается длл говорит, что все эксепшены ловит. Но это почемуто не перехватывается. А в делке как мне его перехватить, если форма уже закрылась, а длл он не выгрузил?
Чел, в программе которого загружается длл говорит, что все эксепшены ловит. Но это почемуто не перехватывается. А в делке как мне его перехватить, если форма уже закрылась, а длл он не выгрузил?
Ага. Нужно бы проверить кто инициализировал закрытие формы. Напр. какая-то кнопка Close или SYSCOMMAND событие. Если SYSCOMMAND и форма не имеет кнопки [x], тогда видимо dll полетел и нет смыла обращаться к его компонентам.
Ага. Нужно бы проверить кто инициализировал закрытие формы. Напр. какая-то кнопка Close или SYSCOMMAND событие. Если SYSCOMMAND и форма не имеет кнопки [x], тогда видимо dll полетел и нет смыла обращаться к его компонентам.
Закрытие формы инициирую я. Кнопка отсутствует. И при нормальном завершении работы без проблем. Сейчас попробую заглушить обработку ошибок фтп-компонента, может в этом причина.
Закрытие формы инициирую я. Кнопка отсутствует. И при нормальном завершении работы без проблем. Сейчас попробую заглушить обработку ошибок фтп-компонента, может в этом причина.
Нет причина не в этом. Отключил всю обработку в компоненте - исключение все равно появляется
Нет причина не в этом. Отключил всю обработку в компоненте - исключение все равно появляется
Пасс. В прошлом году у тебя была такая же проблема с dll.
P.S. А если убрать Action = caFree; ?
Пасс. В прошлом году у тебя была такая же проблема с dll.
P.S. А если убрать Action = caFree; ?
ERangeCheckError или еще какаято по очереди(вылетело из головы) - это раз. Память не очищается - это два. Ну может проблема и схожа - но там проще было - форма запускалась в модальном режиме и мне можно было четко отследить момент загрузки выгрузки. Здесь же форма открывается не модально и момент закрытия не предсказуем. Вариант конечно - запретить пользователю закрывать окно - но это не выход.:)
ERangeCheckError или еще какаято по очереди(вылетело из головы) - это раз. Память не очищается - это два. Ну может проблема и схожа - но там проще было - форма запускалась в модальном режиме и мне можно было четко отследить момент загрузки выгрузки. Здесь же форма открывается не модально и момент закрытия не предсказуем. Вариант конечно - запретить пользователю закрывать окно - но это не выход.:)
Фигней вы ей богу страдаете. Приложив немного ума и старния можно вполне спокойно найти ошибку. Ничего военного здесь нет. Если не наблюдается ни того ни другого - ... Ну а если уж совсем билдеровский прогамер - ну тоды оставь как есть. Звиняй за резкость.
Это чей, немношко измененный пост? :D
Но если всерьез, и конечно как последнее средство, я бы или с Spy или с hook оределил бы какое сообщение получает приложение при сбое и обработал бы в PreTranslateMessage. Конечно в деле это может оказаться не таким уж гладким, как на бумаге...
Фигней вы ей богу страдаете. Приложив немного ума и старния можно вполне спокойно найти ошибку. Ничего военного здесь нет. Если не наблюдается ни того ни другого - ... Ну а если уж совсем билдеровский прогамер - ну тоды оставь как есть. Звиняй за резкость.
Это чей, немношко измененный пост? :D
Но если всерьез, и конечно как последнее средство, я бы или с Spy или с hook оределил бы какое сообщение получает приложение при сбое и обработал бы в PreTranslateMessage. Конечно в деле это может оказаться не таким уж гладким, как на бумаге...
Да вот этим и занимаюсь...:) Проблема как выяснилась, в том, что компонент выполняет листинг директории в момент разрыва связи. Именно это и провоцировало эксепшин и/или ошибки. Правда я считал, что выполнение команды Abort() завершает соединение и прерывает операции но видно я ошибался.
В общем решение проблемы в следующем - выкинул нафиг все VCL-компоненты доступа. Проблема исчезла.:)
По видимому возникновение ошибки можно былобы предотвратить используя при закрытии формы что ни будь типа Wait* - то есть закрывать форму только после того, как компонент завершит все потоки, но решил с этим не заморачиваться и использовать инетапи - гораздо стабильней начало работать.
...
решил с этим не заморачиваться и использовать инетапи - гораздо стабильней начало работать.
А через инетапи у тебя качать с докачкой умеет?
А через инетапи у тебя качать с докачкой умеет?
Пока нет. На ближайшее будущее в функционале это не нужно, а в далеком - планируется полный отказ от ФТП.:)
Но кстати, это возможно? Среди АПИ-мне вроде не попадались функции позволяющие читать по байтам в поток. А может смотрел не внимательно.
...
Но кстати, это возможно? Среди АПИ-мне вроде не попадались функции позволяющие читать по байтам в поток. А может смотрел не внимательно.
FtpCommand(HINTERNET hConnect,
BOOL fExpectResponse,
DWORD dwFlags,
LPCTSTR lpszCommand,
DWORD_PTR dwContext,
HINTERNET* phFtpCommand
);
Сам пока не добрался, думал у тебя есть готовое...
WinInet - вообщем-то штука удобная, но за...ся в этих флагах и константах разбираться.
FtpCommand(HINTERNET hConnect,
BOOL fExpectResponse,
DWORD dwFlags,
LPCTSTR lpszCommand,
DWORD_PTR dwContext,
HINTERNET* phFtpCommand
);
Сам пока не добрался, думал у тебя есть готовое...
WinInet - вообщем-то штука удобная, но за...ся в этих флагах и константах разбираться.
В МСДН пример выглядит так:
HINTERNET hResponse; // To be used for the response info
BOOL bRet = FtpCommand(hConnection, // WinInet Connection handle
TRUE, // Yes, I expect a response
FTP_TRANSFER_TYPE_ASCII, // I'm receiving ASCII
"LIST", // This is the FTP command I am passing
0, // No context needed
&hResponse); // The handle to read the response
if (!bRet)
{
cout << "FtpCommand failed, error: " << GetLastError() << endl;
return;
}
char buff[4096];
DWORD dwBytesRead;
// Read the response
bRet = InternetReadFile(hResponse,
buff,
4095,
&dwBytesRead);
if (!bRet)
{
cout << "InternetReadFile failed, error: " << GetLastError() << endl;
return;
}
// Null terminate response
buff[dwBytesRead] = 0;
cout << "Buffer:\n" << buff << endl;
}
В МСДН пример выглядит так:
А Я начал делать так:
HINTERNET hConnect = NULL;
hSession = InternetOpen ("FTP Session",
INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
if(hSession)
Memo1->Lines->Add("InternetSession OK");
else {
Memo1->Lines->Add("InternetSession FAILED");
return;
}
hConnect = InternetConnect(hSession,
"10.3.10.163",
INTERNET_DEFAULT_FTP_PORT,
NULL,
NULL,
INTERNET_SERVICE_FTP,
NULL,
NULL
);
if(hConnect)
Memo1->Lines->Add("InternetConnect OK");
else {
Memo1->Lines->Add("InternetConnect FAILED");
return;
}
String command("REST 0");
HINTERNET hResponse = NULL;
BOOL Ret = FtpCommand(hConnect,
FALSE,
FTP_TRANSFER_TYPE_BINARY,
command.c_str(),
NULL,
&hResponse);
if(!Ret)
{
Memo1->Lines->Add("Äîêà÷êà íå ïîääåðæèâàåòñÿ");
return;
}
else
Memo1->Lines->Add("Äîêà÷êà ïîääåðæèâàåòñÿ");
...
???