Вероятно, функция немедленно возвращается из-за ошибки.
URLDownloadToFile () определенно является синхронной функцией, если вы установите LPBINDSTATUSCALLBACK lpfnCB как NULL .
Это настолько "синхронно", что никогда не закончится до завершения загрузки, даже если сетевое соединение не удастся и заблокирует ваш поток. Уничтожение потока с помощью URLDownloadToFile (), выполняемого функцией TerminateThread (), приведет к утечке ресурсов и незавершенным дочерним вызовам системных библиотек, и через пару раз URLDownloadToFile () откажется работать в контексте текущего процесса.
Единственный способ надежного использования URLDownloadToFile () без функции обратного вызова - это разветвить отдельный процесс и завершить его, если загрузка останавливается, что потребляет ресурсы.
URLDownloadToFile () загружает поведение точно так же, как IE, все прокси-серверы IE и настройки сети в профиле пользователя, в контексте которых эта функция работает, также будут применяться к этой функции.
Также URLDownloadToFile () не возвращается сразу, даже с функцией обратного вызова. Я считаю необходимым запустить URLDownloadToFile () в отдельном потоке, чтобы безопасно контролировать и прерывать загрузку по сети.
Простой пример функции обратного вызова: https://github.com/choptastic/OldCode-Public/blob/master/URLDownloadToFile/URLDownloadToFile.cpp
.
Чтобы получить безопасную загрузку, вы должны обновить код хотя бы примерно так:
private:
int progress, filesize;
int AbortDownload;
public:
STDMETHOD(OnStartBinding)(
{
AbortDownload=0;
progress=0;
filesize=0;
return E_NOTIMPL; }
STDMETHOD(GetProgress)()
{ return progress; }
STDMETHOD(GetFileSize)()
{ return filesize; }
STDMETHOD(AbortDownl)()
{
AbortDownload=1;
return E_NOTIMPL; }
HRESULT DownloadStatus::OnProgress ( ULONG ulProgress, ULONG ulProgressMax,ULONG ulStatusCode, LPCWSTR wszStatusText )
{
progress=ulProgress;
filesize=ulProgressMax;
if (AbortDownload) return E_ABORT;
return S_OK;
}
, чтобы вы всегда могли прервать загрузку и проверить ход загрузки.
Даже после того, как загрузка была указана как выполненная с помощью S_OK, возвращенного функцией URLDownloadToFile (), вы должны сравнивать значения progress == filesize, потому что URLDownloadToFile () может по ошибке прервать загрузку с S_OK, например, если соединение установлено через сетевой мост локальных сетевых интерфейсов и мостов по какой-то причине упали.
Также следует обратить внимание на функцию DeleteUrlCacheEntry () в паре с URLDownloadToFile (), чтобы освободить место на диске после загрузки, поскольку весь загружаемый контент по умолчанию кэшируется на диске в соответствии с политикой кэширования IE.