Problem z algorytmem do pobierania pliku

0

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?

errors.JPG

dodanie obrazka do posta + zmiana tematu wątku - fp

0

I pewnie debugować się nie da i zobaczyć na czym "się wywala", bo przecież lepiej napisać na forum.

0

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.

0

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.

0

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ć.

0

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.

1 użytkowników online, w tym zalogowanych: 0, gości: 1