Ten kod http://www.delphibasics.info/home/delphibasicssnippets/winsockdownloader kompiluje sie i program pobiera plik ale pojawiają się błędy - jak poprawić kod by uniknać tych błędów?
dodanie obrazka do posta + zmiana tematu wątku - fp
Ten kod http://www.delphibasics.info/home/delphibasicssnippets/winsockdownloader kompiluje sie i program pobiera plik ale pojawiają się błędy - jak poprawić kod by uniknać tych błędów?
dodanie obrazka do posta + zmiana tematu wątku - fp
I pewnie debugować się nie da i zobaczyć na czym "się wywala", bo przecież lepiej napisać na forum.
Nie analizowałem tego kodu, ale prościej skorzystać z modułu dostępnego z przykładami na stronie: http://piechnat.pl/article/simpletcp.html - jeżeli chcesz na przykład pod czystym WinAPI operować na socketach i łączyć się po TCP lub postawić własny serwer dla tego protokołu.
Kod działa bez błędów jeśli jest napisany w exe (bo domyślnie w uses jest dodany Dialogs). Do biblioteki dll dodałem przypadkowo klasę Dialogs i teraz już nie pokazuje błędów ale rozmiar dll'ki zwiększył sie o 300KB. Wywala się na shellexecute chyba.
Tzn. w kodzie tego programu exe początkowo w uses miałem tylko: Windows, Winsock, ShellApi; I program sie kompilował , pobierał plik ale wyskakiwaly te bledy i nieuruchamial pobranego pliku. Wywalal sie na ShellExecute. Po dodaniu klasy Dialogs błędy nie pojawiają się i uruchamiany jest pobrany plik (ShellExecute nie generuje już błędów). Kodzik dziala takżę z poziomu dll.
Być może Twój antywirus blokuje Ci pobieranie tego pliku i wykonywanie tego kodu. Stąd błędy access violation. Kiedy wyłącze u siebie tymczasowo ochronę w ESS6 to ten kod, do którego podałeś link - kompiluje się do exe, a program pobiera plik do żądanej lokalizacji, którą zmieniłem tylko z c:\
na D:\
. Nie wiem dlaczego nadal upierasz się na korzystanie z kodu, który już wcześniej masa gimbusiarni wykorzystała przy tworzeniu malware i niestety dlatego wiele programów AV się czepia takiego exeka. Skorzystaj z SimpleTCP jak Tobie radziłem i unikniesz problemów. Przykład kodu jest. Wyłuskanie nagłówków i zapisywanie do stworzonego przez funkcje WinAPI pliku pozostałego bufora to żaden problem. Wystarczy siąść, pomyśleć i po prostu napisać.
Napisałem przykład pobierania pliku w oparciu o WinINet. Kod napisany jest tak aby nie korzystał z innych modułów poza Windows może się przyda:
unit uDownloadFile;
interface
uses
Windows;
type
HINTERNET = Pointer;
//DownloadFile - pobieranie plik z Internetu
//parametry:
//ASource adres źródła
//ADest - docelowa ścieżka i nazwa pliku
function DownloadFile(ASource, ADest: string): Boolean;
//function GetFileSizeEx(hFile: Cardinal; var lpFileSize: Int64): BOOL;
// stdcall; external 'kernel32.dll';
function InternetOpen(lpszAgent: PAnsiChar; dwAccessType: DWORD;
lpszProxy, lpszProxyBypass: PAnsiChar; dwFlags: DWORD): HINTERNET; stdcall;
external 'wininet.dll' name 'InternetOpenA';
function InternetOpenUrl(hInet: HINTERNET; lpszUrl: PAnsiChar;
lpszHeaders: PAnsiChar; dwHeadersLength: DWORD; dwFlags: DWORD;
dwContext: DWORD): HINTERNET; stdcall; external 'wininet.dll'
name 'InternetOpenUrlA';
function HttpQueryInfo(hRequest: HINTERNET; dwInfoLevel: DWORD;
lpvBuffer: Pointer; var lpdwBufferLength: DWORD;
var lpdwReserved: DWORD): BOOL; stdcall; external 'wininet.dll'
name 'HttpQueryInfoA';
function InternetReadFile(hFile: HINTERNET; lpBuffer: Pointer;
dwNumberOfBytesToRead: DWORD; var lpdwNumberOfBytesRead: DWORD): BOOL;
stdcall; external 'wininet.dll';
function InternetCloseHandle(hInet: HINTERNET): BOOL; stdcall;
external 'wininet.dll';
const
INTERNET_OPEN_TYPE_PRECONFIG = 0;
INTERNET_FLAG_RELOAD = $80000000;
HTTP_QUERY_CONTENT_LENGTH = 5;
implementation
function DownloadFile(ASource, ADest: string): Boolean;
const
UA = 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:22.0) Gecko/20100101 Firefox/22.0';
var
hInet, hInternetFile: HINTERNET;
hDownloadFile: Cardinal;
lpBuffer: array[0..1024] of Char;
dwBufSize, dwDummy, dwBytesRead: Cardinal;
dwInternetFileSize, dwFileSize: Int64;
begin
result:= False;
hInet:= InternetOpen(UA, INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
if Assigned(hInet) then
begin
hInternetFile:= InternetOpenURL(hInet, PAnsiChar(ASource), nil, 0,
INTERNET_FLAG_RELOAD, 0);
if Assigned(hInternetFile) then
begin
ZeroMemory(@lpBuffer, SizeOf(lpBuffer));
dwBufSize:= SizeOf(lpBuffer);
dwDummy:= 0;
if HTTPQueryInfo(hInternetFile, HTTP_QUERY_CONTENT_LENGTH, @lpBuffer,
dwBufSize, dwDummy) then
begin
Val(lpBuffer, dwInternetFileSize, dwDummy);
dwFileSize:= 0;
hDownloadFile:= CreateFile(PAnsiChar(ADest), GENERIC_WRITE,
FILE_SHARE_WRITE, nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if (hDownloadFile > 0) then
begin
repeat
InternetReadFile(hInternetFile, @lpBuffer, SizeOf(lpBuffer),
dwBytesRead);
WriteFile(hDownloadFile, lpBuffer, dwBytesRead, dwDummy, nil);
dwFileSize:= dwFileSize + dwDummy;
//tu można by zrobić obslugę ProgressBar
until (dwBytesRead = 0) or (dwDummy = 0);
//GetFileSizeEx(hDownloadFile, dwFileSize);
result:= (dwInternetFileSize = dwFileSize);
CloseHandle(hDownloadFile);
if not result then
Windows.DeleteFile(PAnsiChar(ADest));
end;
end;
InternetCloseHandle(hInternetFile);
end;
InternetCloseHandle(hInet);
end;
end;
end.