您的当前位置:首页>关注 > 正文

urlmon.dll网络操作API——URL语言函数 即时焦点

来源:CSDN 时间:2023-04-26 13:50:26

URLDownloadToFile是urlmon.dll提供的网络操作API,可以用于从指定的URL下载文件到本地,在C++中通过类很容易实现下载进度的获取,今天需要在C语言中使用到这个函数,这里记录一下使用方法。该函数的定义如下所示。


(相关资料图)

HRESULT URLDownloadToFile(

LPUNKNOWN pCaller,

LPCTSTR szURL,

LPCTSTR szFileName,

_Reserved_ DWORD dwReserved,

LPBINDSTATUSCALLBACK lpfnCB

);

参数pCaller跟ActiveX和COM有关,如有兴趣参考

参数szURL为下载地址,地址的协议必须要是IE浏览器所支持的

参数szFileName为文件最终的保存路径,例如C:/a.txt

参数dwReserved保留,始终为0

参数lpfnCB是一个IBindStatusCallback指针。

在urlmon.h头文件的定义中,C语言风格的接口定义如下:

typedef struct IBindStatusCallbackVtbl

{

BEGIN_INTERFACE

HRESULT ( STDMETHODCALLTYPE *QueryInterface )(

__RPC__in IBindStatusCallback * This,

/* [in] */ __RPC__in REFIID riid,

/* [annotation][iid_is][out] */

_COM_Outptr_ void **ppvObject);

ULONG ( STDMETHODCALLTYPE *AddRef )(

__RPC__in IBindStatusCallback * This);

ULONG ( STDMETHODCALLTYPE *Release )(

__RPC__in IBindStatusCallback * This);

HRESULT ( STDMETHODCALLTYPE *OnStartBinding )(

__RPC__in IBindStatusCallback * This,

/* [in] */ DWORD dwReserved,

/* [in] */ __RPC__in_opt IBinding *pib);

HRESULT ( STDMETHODCALLTYPE *GetPriority )(

__RPC__in IBindStatusCallback * This,

/* [out] */ __RPC__out LONG *pnPriority);

HRESULT ( STDMETHODCALLTYPE *OnLowResource )(

__RPC__in IBindStatusCallback * This,

/* [in] */ DWORD reserved);

HRESULT ( STDMETHODCALLTYPE *OnProgress )(

__RPC__in IBindStatusCallback * This,

/* [in] */ ULONG ulProgress,

/* [in] */ ULONG ulProgressMax,

/* [in] */ ULONG ulStatusCode,

/* [unique][in] */ __RPC__in_opt LPCWSTR szStatusText);

HRESULT ( STDMETHODCALLTYPE *OnStopBinding )(

__RPC__in IBindStatusCallback * This,

/* [in] */ HRESULT hresult,

/* [unique][in] */ __RPC__in_opt LPCWSTR szError);

/* [local] */ HRESULT ( STDMETHODCALLTYPE *GetBindInfo )(

IBindStatusCallback * This,

/* [out] */ DWORD *grfBINDF,

/* [unique][out][in] */ BINDINFO *pbindinfo);

/* [local] */ HRESULT ( STDMETHODCALLTYPE *OnDataAvailable )(

IBindStatusCallback * This,

/* [in] */ DWORD grfBSCF,

/* [in] */ DWORD dwSize,

/* [in] */ FORMATETC *pformatetc,

/* [in] */ STGMEDIUM *pstgmed);

HRESULT ( STDMETHODCALLTYPE *OnObjectAvailable )(

__RPC__in IBindStatusCallback * This,

/* [in] */ __RPC__in REFIID riid,

/* [iid_is][in] */ __RPC__in_opt IUnknown *punk);

END_INTERFACE

} IBindStatusCallbackVtbl;

interface IBindStatusCallback

{

CONST_VTBL struct IBindStatusCallbackVtbl *lpVtbl;

};

这里的interface在C语言中的定义为struct, IBindStatusCallback回调实际上就是一个结构体,结构体只有一个字段IBindStatusCallbackVtbl *指针,你需要做的就是对这个结构体内的IBindStatusCallbackVtbl 指针进行实例化。IBindStatusCallbackVtbl 结构中包含了一系列的函数指针,也就是用于URLDownloadToFile下载时的回调函数。若要实现下载进度的获取,只需要在OnProgress回调中处理即可。

控制台示例代码

#define _CRT_SECURE_NO_WARNINGS

#include

#include

#include

#pragma comment(lib,"urlmon")

HRESULT (STDMETHODCALLTYPE QueryInterface)(

IBindStatusCallback* This,

/* [in] */ REFIID riid,

/* [iid_is][out] */ void** ppvObject)

{

return E_NOTIMPL;

}

ULONG (STDMETHODCALLTYPE AddRef)(

IBindStatusCallback* This)

{

return E_NOTIMPL;

}

ULONG (STDMETHODCALLTYPE Release)(

IBindStatusCallback* This)

{

return E_NOTIMPL;

}

HRESULT (STDMETHODCALLTYPE OnStartBinding)(

IBindStatusCallback* This,

/* [in] */ DWORD dwReserved,

/* [in] */ IBinding* pib)

{

return E_NOTIMPL;

}

HRESULT (STDMETHODCALLTYPE GetPriority)(

IBindStatusCallback* This,

/* [out] */ LONG* pnPriority)

{

return E_NOTIMPL;

}

HRESULT (STDMETHODCALLTYPE OnLowResource)(

IBindStatusCallback* This,

/* [in] */ DWORD reserved)

{

return E_NOTIMPL;

}

HRESULT (STDMETHODCALLTYPE OnProgress)(

IBindStatusCallback* This,

/* [in] */ ULONG ulProgress,

/* [in] */ ULONG ulProgressMax,

/* [in] */ ULONG ulStatusCode,

/* [in] */ LPCWSTR szStatusText)

{

if (ulProgress == 0) {

return S_OK;

}

printf("%d / %d bytes , %.2f%%\n",

ulProgress, ulProgressMax,100*(double)ulProgress/(double)ulProgressMax);

return S_OK;

}

HRESULT (STDMETHODCALLTYPE OnStopBinding)(

IBindStatusCallback* This,

/* [in] */ HRESULT hresult,

/* [unique][in] */ LPCWSTR szError)

{

return E_NOTIMPL;

}

HRESULT (STDMETHODCALLTYPE GetBindInfo)(

IBindStatusCallback* This,

/* [out] */ DWORD* grfBINDF,

/* [unique][out][in] */ BINDINFO* pbindinfo)

{

return E_NOTIMPL;

}

HRESULT (STDMETHODCALLTYPE OnDataAvailable)(

IBindStatusCallback* This,

/* [in] */ DWORD grfBSCF,

/* [in] */ DWORD dwSize,

/* [in] */ FORMATETC* pformatetc,

/* [in] */ STGMEDIUM* pstgmed)

{

return E_NOTIMPL;

}

HRESULT (STDMETHODCALLTYPE OnObjectAvailable)(

IBindStatusCallback* This,

/* [in] */ REFIID riid,

/* [iid_is][in] */ IUnknown* punk)

{

return E_NOTIMPL;

}

int main(int argc,char * argv[]) {

char path[MAX_PATH];

char downloadURL[] ="https://down.qq.com/qqweb/PCQQ/PCQQ_EXE/PCQQ2020.exe";

IBindStatusCallback callBack;

IBindStatusCallbackVtbl vtbl;

vtbl.QueryInterface = QueryInterface;

vtbl.AddRef = AddRef;

vtbl.Release = Release;

vtbl.OnStartBinding = OnStartBinding;

vtbl.GetPriority = GetPriority;

vtbl.OnLowResource = OnLowResource;

vtbl.OnProgress = OnProgress;//进度回调操作

vtbl.OnStopBinding = OnStopBinding;

vtbl.GetBindInfo = GetBindInfo;

vtbl.OnDataAvailable = OnDataAvailable;

vtbl.OnObjectAvailable = OnObjectAvailable;

callBack.lpVtbl = &vtbl;

GetTempPath(sizeof(path),path);

strcat(path, "tmpqq.exe");

printf("保存位置: %s\n", path);

URLDownloadToFile(NULL,downloadURL, path,0,&callBack);

return 0;

}

扫码领个红包作为打赏吧~~

(余额宝支付时可抵现)

喜欢 (2)or分享 (0)

标签:

最新新闻:

新闻放送
Top