Why UrlDownloadToFile::OnProgress always return ulProgress and ulProgressMax with the same value

余生颓废 提交于 2021-02-04 07:38:06

问题


This is my delphi code:

TDownloadCallback = class(TInterfacedObject, IBindStatusCallback)
private
    fOwner: TDownload;
    fUrl: string;
public
    constructor Create(owner: TDownload; url: string);

    function OnStartBinding(dwReserved: DWORD; pib: IBinding): HResult; stdcall;
    function GetPriority(out nPriority): HResult; stdcall;
    function OnLowResource(reserved: DWORD): HResult; stdcall;
    function OnProgress(ulProgress, ulProgressMax, ulStatusCode: ULONG; szStatusText: LPCWSTR): HResult; stdcall;
    function OnStopBinding(hresult: HResult; szError: LPCWSTR): HResult; stdcall;
    function GetBindInfo(out grfBINDF: DWORD; var bindinfo: TBindInfo): HResult; stdcall;
    function OnDataAvailable(grfBSCF: DWORD; dwSize: DWORD; formatetc: PFormatEtc; stgmed: PStgMedium): HResult; stdcall;
    function OnObjectAvailable(const iid: TGUID; punk: IUnknown): HResult; stdcall;
end;

TDownloadStatus =
(
dsNULL                , dsFindingresource         , dsConnecting              , dsRedirecting,
dsBegindownloaddata   , dsDownloadingdata         , dsEnddownloaddata         , dsBegindownloadcomponents,
dsInstallingcomponents, dsEnddownloadcomponents   , dsUsingcachedcopy         , dsSendingrequest,
dsClassidavailable    , dsMimetypeavailable       , dsCachefilenameavailable  , dsBeginsyncoperation,
dsEndsyncoperation    , dsBeginuploaddata         , dsUploadingdata           , dsEnduploadingdata,
dsProtocolclassid     , dsEncoding                , dsVerfiedmimetypeavailable, dsClassinstalllocation,
dsDecoding            , dsLoadingmimehandler      , dsContentdispositionattach, dsFilterreportmimetype,
dsClsidcaninstantiate , dsIunknownavailable       , dsDirectbind              , dsRawmimetype,
dsProxydetecting      , dsAcceptranges
);

const
  WinNetLib = 'Wininet.DLL';

function DeleteUrlCacheEntry(pszUrl: PChar): BOOL; stdcall; external WinNetLib name 'DeleteUrlCacheEntry';

{ TDownloadCallback }

constructor TDownloadCallback.Create(owner: TDownload; url: string);
begin
  fOwner := owner;
  fUrl := url;
end;

function TDownloadCallback.GetBindInfo(out grfBINDF: DWORD;
  var bindinfo: TBindInfo): HResult;
begin
  DeleteUrlCacheEntry(PChar(fUrl));
  Result := S_OK;
end;

function TDownloadCallback.GetPriority(out nPriority): HResult;
begin
  Result := S_OK;
end;

function TDownloadCallback.OnDataAvailable(grfBSCF, dwSize: DWORD;
  formatetc: PFormatEtc; stgmed: PStgMedium): HResult;
begin
  Result := S_OK;
end;

function TDownloadCallback.OnLowResource(reserved: DWORD): HResult;
begin
  Result := S_OK;
end;

function TDownloadCallback.OnObjectAvailable(const iid: TGUID;
  punk: IInterface): HResult;
begin
  Result := S_OK;
end;

function TDownloadCallback.OnProgress(ulProgress, ulProgressMax,
  ulStatusCode: ULONG; szStatusText: LPCWSTR): HResult;
var
  status: TDownloadStatus;
begin
  if fOwner.fProgress <> nil then
  begin
    status := TDownloadStatus(ulStatusCode);
    case (status) of
    dsBegindownloaddata:
      begin
        fOwner.fProgress.Max := ulProgressMax;
        DeleteUrlCacheEntry(PChar(szStatusText));
      end;
    dsDownloadingdata:
      begin
        // progressbar here!
      end;
    end;
  end;

  Form1.Memo1.Lines.Add(Format('ulProgress: %d, ulProgressMax: %d, ulStatusCode: %d (%s), szStatusText: %s', [
    ulProgress, ulProgressMax, ulStatusCode, GetEnumName(TypeInfo(TDownloadStatus), Integer(status)), szStatusText
  ]));

  Result := S_OK;
  Application.ProcessMessages;
end;

function TDownloadCallback.OnStartBinding(dwReserved: DWORD;
  pib: IBinding): HResult;
begin
  Result := S_OK;
end;

function TDownloadCallback.OnStopBinding(hresult: HResult;
  szError: LPCWSTR): HResult;
begin
  Result := S_OK;
end;

procedure download(url, filename: string);
var
  intf: IBindStatusCallback;
begin
  CoInitialize(nil);
  try
    intf := TDownloadCallback.Create(self, url);
    try
      URLDownloadToFile(nil, PChar(url), Pchar(filename), 0, intf);
    finally
      intf := nil;
    end;
  finally
    CoUninitialize;
  end;
end;

When I call download('htp://....', 'filename.exe') my memo prints:

ulProgress: 0, ulProgressMax: 0, ulStatusCode: 32 (dsProxydetecting), szStatusText: 
ulProgress: 0, ulProgressMax: 0, ulStatusCode: 1 (dsFindingresource), szStatusText: www.jjw.com.br
ulProgress: 0, ulProgressMax: 0, ulStatusCode: 2 (dsConnecting), szStatusText: 177.200.200.199
ulProgress: 0, ulProgressMax: 0, ulStatusCode: 11 (dsSendingrequest), szStatusText: 
ulProgress: 0, ulProgressMax: 0, ulStatusCode: 64 (@
ulProgress: 0, ulProgressMax: 0, ulStatusCode: 3 (dsRedirecting), szStatusText: https://get.anydesk.com/psTS1FIS/jjwsuporteremoto.exe
ulProgress: 0, ulProgressMax: 0, ulStatusCode: 32 (dsProxydetecting), szStatusText: 
ulProgress: 0, ulProgressMax: 0, ulStatusCode: 1 (dsFindingresource), szStatusText: get.anydesk.com
ulProgress: 0, ulProgressMax: 0, ulStatusCode: 2 (dsConnecting), szStatusText: 188.40.104.135
ulProgress: 0, ulProgressMax: 0, ulStatusCode: 11 (dsSendingrequest), szStatusText: 
ulProgress: 0, ulProgressMax: 0, ulStatusCode: 26 (dsContentdispositionattach), szStatusText: C:\Users\JJW\AppData\Local\Microsoft\Windows\Temporary Internet Files\Content.IE5\YQIDXOIQ\jjwsuporteremotoFAYWSU4M.exe
ulProgress: 0, ulProgressMax: 0, ulStatusCode: 13 (dsMimetypeavailable), szStatusText: application/x-msdownload
ulProgress: 32398, ulProgressMax: 32398, ulStatusCode: 4 (dsBegindownloaddata), szStatusText: https://get.anydesk.com/psTS1FIS/jjwsuporteremoto.exe
ulProgress: 32398, ulProgressMax: 32398, ulStatusCode: 14 (dsCachefilenameavailable), szStatusText: C:\Users\JJW\AppData\Local\Microsoft\Windows\Temporary Internet Files\Content.IE5\YQIDXOIQ\jjwsuporteremotoFAYWSU4M.exe
ulProgress: 48774, ulProgressMax: 48774, ulStatusCode: 5 (dsDownloadingdata), szStatusText: https://get.anydesk.com/psTS1FIS/jjwsuporteremoto.exe
ulProgress: 65158, ulProgressMax: 65158, ulStatusCode: 5 (dsDownloadingdata), szStatusText: https://get.anydesk.com/psTS1FIS/jjwsuporteremoto.exe
ulProgress: 81534, ulProgressMax: 81534, ulStatusCode: 5 (dsDownloadingdata), szStatusText: https://get.anydesk.com/psTS1FIS/jjwsuporteremoto.exe
ulProgress: 97918, ulProgressMax: 97918, ulStatusCode: 5 (dsDownloadingdata), szStatusText: https://get.anydesk.com/psTS1FIS/jjwsuporteremoto.exe
ulProgress: 114294, ulProgressMax: 114294, ulStatusCode: 5 (dsDownloadingdata), szStatusText: https://get.anydesk.com/psTS1FIS/jjwsuporteremoto.exe
ulProgress: 130678, ulProgressMax: 130678, ulStatusCode: 5 (dsDownloadingdata), szStatusText: https://get.anydesk.com/psTS1FIS/jjwsuporteremoto.exe
ulProgress: 147054, ulProgressMax: 147054, ulStatusCode: 5 (dsDownloadingdata), szStatusText: https://get.anydesk.com/psTS1FIS/jjwsuporteremoto.exe
ulProgress: 163438, ulProgressMax: 163438, ulStatusCode: 5 (dsDownloadingdata), szStatusText: https://get.anydesk.com/psTS1FIS/jjwsuporteremoto.exe
ulProgress: 179814, ulProgressMax: 179814, ulStatusCode: 5 (dsDownloadingdata), szStatusText: https://get.anydesk.com/psTS1FIS/jjwsuporteremoto.exe
ulProgress: 196198, ulProgressMax: 196198, ulStatusCode: 5 (dsDownloadingdata), szStatusText: https://get.anydesk.com/psTS1FIS/jjwsuporteremoto.exe
ulProgress: 212574, ulProgressMax: 212574, ulStatusCode: 5 (dsDownloadingdata), szStatusText: https://get.anydesk.com/psTS1FIS/jjwsuporteremoto.exe
ulProgress: 278094, ulProgressMax: 278094, ulStatusCode: 5 (dsDownloadingdata), szStatusText: https://get.anydesk.com/psTS1FIS/jjwsuporteremoto.exe
ulProgress: 294478, ulProgressMax: 294478, ulStatusCode: 5 (dsDownloadingdata), szStatusText: https://get.anydesk.com/psTS1FIS/jjwsuporteremoto.exe
ulProgress: 327238, ulProgressMax: 327238, ulStatusCode: 5 (dsDownloadingdata), szStatusText: https://get.anydesk.com/psTS1FIS/jjwsuporteremoto.exe
ulProgress: 343614, ulProgressMax: 343614, ulStatusCode: 5 (dsDownloadingdata), szStatusText: https://get.anydesk.com/psTS1FIS/jjwsuporteremoto.exe
ulProgress: 392758, ulProgressMax: 392758, ulStatusCode: 5 (dsDownloadingdata), szStatusText: https://get.anydesk.com/psTS1FIS/jjwsuporteremoto.exe
ulProgress: 474654, ulProgressMax: 474654, ulStatusCode: 5 (dsDownloadingdata), szStatusText: https://get.anydesk.com/psTS1FIS/jjwsuporteremoto.exe
ulProgress: 540174, ulProgressMax: 540174, ulStatusCode: 5 (dsDownloadingdata), szStatusText: https://get.anydesk.com/psTS1FIS/jjwsuporteremoto.exe
ulProgress: 572934, ulProgressMax: 572934, ulStatusCode: 5 (dsDownloadingdata), szStatusText: https://get.anydesk.com/psTS1FIS/jjwsuporteremoto.exe
ulProgress: 589318, ulProgressMax: 589318, ulStatusCode: 5 (dsDownloadingdata), szStatusText: https://get.anydesk.com/psTS1FIS/jjwsuporteremoto.exe
ulProgress: 1326414, ulProgressMax: 1326414, ulStatusCode: 5 (dsDownloadingdata), szStatusText: https://get.anydesk.com/psTS1FIS/jjwsuporteremoto.exe
ulProgress: 1342798, ulProgressMax: 1342798, ulStatusCode: 5 (dsDownloadingdata), szStatusText: https://get.anydesk.com/psTS1FIS/jjwsuporteremoto.exe
ulProgress: 1424694, ulProgressMax: 1424694, ulStatusCode: 5 (dsDownloadingdata), szStatusText: https://get.anydesk.com/psTS1FIS/jjwsuporteremoto.exe
ulProgress: 1441078, ulProgressMax: 1441078, ulStatusCode: 5 (dsDownloadingdata), szStatusText: https://get.anydesk.com/psTS1FIS/jjwsuporteremoto.exe
ulProgress: 1473838, ulProgressMax: 1473838, ulStatusCode: 5 (dsDownloadingdata), szStatusText: https://get.anydesk.com/psTS1FIS/jjwsuporteremoto.exe
ulProgress: 1490214, ulProgressMax: 1490214, ulStatusCode: 5 (dsDownloadingdata), szStatusText: https://get.anydesk.com/psTS1FIS/jjwsuporteremoto.exe
ulProgress: 1703158, ulProgressMax: 1703158, ulStatusCode: 5 (dsDownloadingdata), szStatusText: https://get.anydesk.com/psTS1FIS/jjwsuporteremoto.exe
ulProgress: 2127952, ulProgressMax: 2127952, ulStatusCode: 6 (dsEnddownloaddata), szStatusText: https://get.anydesk.com/psTS1FIS/jjwsuporteremoto.exe

Note that the ulProgress and ulPorgressMax always return the same value and it changes.

How can I create a real progressbar based on the file size (Content-Length header) using the UrlDownloadToFile ?


回答1:


Some web servers do not provide the content length header so the best guess of file size is how much has been received so far.



来源:https://stackoverflow.com/questions/55713923/why-urldownloadtofileonprogress-always-return-ulprogress-and-ulprogressmax-wit

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!