おそらく関数はエラーのためにすぐに戻ります。
LPBINDSTATUSCALLBACK lpfnCBをNULLに設定した場合、URLDownloadToFile()は間違いなく同期関数です。
これは非常に「同期的」であり、ネットワーク接続に障害が発生してスレッドがブロックされた場合でも、ダウンロードが完了するまで終了することはありません。TerminateThread()関数によって進行中のURLDownloadToFile()でスレッドを強制終了すると、リソースリークが発生し、システムdllへの子呼び出しが完了せず、数回後に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;
}
そのため、いつでもダウンロードを中止して、ダウンロードの進行状況を確認できます。
URLDownloadToFile()関数によって返されるS_OKによってダウンロードが完了したことが示された後でも、たとえばローカルネットワークのネットワークブリッジを介して接続されている場合、URLDownloadToFile()が誤ってS_OKとダウンロードをドロップする可能性があるため、progress==filesize値を比較する必要があります。インターフェイスとブリッジが何らかの理由でダウンしました。
また、ダウンロード後にディスク領域を解放するには、URLDownloadToFile()と組み合わせたDeleteUrlCacheEntry()関数に注意する必要があります。これは、ダウンロードされたすべてのコンテンツが、IEのキャッシュポリシーに従ってデフォルトでディスクにキャッシュされるためです。