#delphi #download
#delphi #Скачать
Вопрос:
Это мой код delphi:
TDownloadCallback = class(TInterfacedObject, IBindStatusCallback)
private
fOwner: TDownload;
fUrl: string;
public
constructor Create(owner: TDownload; url: string);
function OnStartBinding(dwReserved: DWORD; pib: IBinding): HResu< stdcall;
function GetPriority(out nPriority): HResu< stdcall;
function OnLowResource(reserved: DWORD): HResu< stdcall;
function OnProgress(ulProgress, ulProgressMax, ulStatusCode: ULONG; szStatusText: LPCWSTR): HResu< stdcall;
function OnStopBinding(hresult: HResu< szError: LPCWSTR): HResu< stdcall;
function GetBindInfo(out grfBINDF: DWORD; var bindinfo: TBindInfo): HResu< stdcall;
function OnDataAvailable(grfBSCF: DWORD; dwSize: DWORD; formatetc: PFormatEtc; stgmed: PStgMedium): HResu< stdcall;
function OnObjectAvailable(const iid: TGUID; punk: IUnknown): HResu< 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): HResu<
begin
DeleteUrlCacheEntry(PChar(fUrl));
Result := S_OK;
end;
function TDownloadCallback.GetPriority(out nPriority): HResu<
begin
Result := S_OK;
end;
function TDownloadCallback.OnDataAvailable(grfBSCF, dwSize: DWORD;
formatetc: PFormatEtc; stgmed: PStgMedium): HResu<
begin
Result := S_OK;
end;
function TDownloadCallback.OnLowResource(reserved: DWORD): HResu<
begin
Result := S_OK;
end;
function TDownloadCallback.OnObjectAvailable(const iid: TGUID;
punk: IInterface): HResu<
begin
Result := S_OK;
end;
function TDownloadCallback.OnProgress(ulProgress, ulProgressMax,
ulStatusCode: ULONG; szStatusText: LPCWSTR): HResu<
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): HResu<
begin
Result := S_OK;
end;
function TDownloadCallback.OnStopBinding(hresult: HResu<
szError: LPCWSTR): HResu<
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;
Когда я вызываю download('htp://....', 'filename.exe')
свою заметку, печатается:
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:UsersJJWAppDataLocalMicrosoftWindowsTemporary Internet FilesContent.IE5YQIDXOIQjjwsuporteremotoFAYWSU4M.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:UsersJJWAppDataLocalMicrosoftWindowsTemporary Internet FilesContent.IE5YQIDXOIQjjwsuporteremotoFAYWSU4M.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
Обратите внимание, что ulProgress
и ulPorgressMax
всегда возвращают одно и то же значение, и оно меняется.
Как я могу создать реальную progressbar на основе размера файла (заголовок Content-Length), используя UrlDownloadToFile
?
Комментарии:
1. Некоторые веб-серверы не предоставляют заголовок content length, поэтому лучшее предположение о размере файла — это то, сколько вы уже получили.
2. @Brian спасибо за трюк, это была моя ошибка. Вы можете ответить на вопрос этим комментарием, и я приму его.
3. Обратите внимание, что это даже указано в
OnProgress
документации : » ulProgressMax [in] Длинное целое число без знака, которое содержит ожидаемое максимальное значение параметра ulProgress для продолжительности вызовов IBindStatusCallback::OnProgress для этой операции привязки. Обратите внимание, что это значение может меняться при вызовах этого метода. Нулевое значение означает, что максимальное значение ulProgress неизвестно ; например, в методе IMoniker::BindToStorage, когда размер загружаемых данных неизвестен. »4. @RemyLebeau единственный случай здесь заключается в том, что api не отправляет НОЛЬ, он всегда отправляет «загруженный размер».
5. @BetoNeto тем не менее, это подпадает под документально подтвержденное предложение «это значение может изменяться при вызовах этого метода».
Ответ №1:
Некоторые веб-серверы не предоставляют заголовок content length, поэтому лучшее предположение о размере файла — это то, сколько было получено на данный момент.
Комментарии:
1. Ресурс / загрузка может быть создана «на лету» (т. Е. TAR или ZIP) и предлагается как таковой сразу, вместо того, чтобы ждать, пока он не будет готов полностью — аналогично, общий размер файла может быть даже неизвестен серверу.