虽然可以使用 URLDownloadFileToXXX() 这个 API,但是,它在使用了代理的时候会遇到麻烦。
这点,Windows 自动更新发生过这样的问题:如果使用了 IE 代理,如果下载代码位于系统帐号
下,代理设置可能会失效。当然,也可以为系统帐号手动设置代理(其实就是 IE 的代理的设置
方法),不过,程序会受到很多的限制。
所以,可以考虑使用下属两个函数进行使用 - 服务程序亦可。^_^[code]//
// Download a file from the URL.
bool CHttpDownload::UrlDownloadToFile(TCHAR *ptszURL, TCHAR *ptszFilePath)
{
HINTERNET hNet;
HINTERNET hFile;
std::string sProxyServer;
DWORD dwStatusCode;
TCHAR dwStatusCode1[32] = {0};
DWORD dwSize1 = sizeof(dwStatusCode1), dwSize = sizeof(DWORD);
int nfilesize; // file size, 2GB limited. ;)
m_sUrl = ptszURL;
//OutputDebugString("/nCHttpDownload::UrlDownloadToFile() ++");
//
if(m_ConnectionType == UseProxy)
{
//OutputDebugString("/n ==> Useproxy");
hNet = InternetOpen(tszAgent, INTERNET_OPEN_TYPE_PROXY, m_sProxy.c_str(), NULL, 0);
}
else if(m_ConnectionType == DirectToInternet)
{
//OutputDebugString("/n ==> DirectToInternet");
hNet = InternetOpen(tszAgent, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
}
else if(m_ConnectionType == UsePreConfig)
{
//OutputDebugString("/n ==> UsePreConfig");
hNet = InternetOpen(tszAgent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
}
if(hNet == NULL)
{
//OutputDebugString("/nCHttpDownload::UrlDownloadToFile() --.1");
return false;
}
hFile = InternetOpenUrl(hNet, m_sUrl.c_str(), NULL, 0, 0, 0);
if(hFile == NULL)
{
InternetCloseHandle(hNet) ;
//OutputDebugString(m_sUrl.c_str());
//OutputDebugString(ptszURL);
//OutputDebugString("/nCHttpDownload::UrlDownloadToFile() --.2");
return false;
}
BOOL bRet = HttpQueryInfo(hFile, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER,&dwStatusCode,&dwSize,NULL);
if(200 != dwStatusCode) // if URI is not exist, give up.
{
InternetCloseHandle(hNet) ;
InternetCloseHandle(hFile) ;
//OutputDebugString("/nCHttpDownload::UrlDownloadToFile() --.3");
return false;
}
if(HttpQueryInfo(hFile,HTTP_QUERY_CONTENT_LENGTH, &dwStatusCode1,&dwSize1,NULL))
{
nfilesize = atoi(dwStatusCode1); // file size.
}
HANDLE hDownFile = CreateFile(ptszFilePath,
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if(INVALID_HANDLE_VALUE == hDownFile)
{
InternetCloseHandle(hNet) ;
InternetCloseHandle(hFile) ;
//OutputDebugString("/nCHttpDownload::UrlDownloadToFile() --.4");
return false;
}
// O.K. save file
DWORD dwWrite, dwBytesRead = 0;
char bufFile[MAX_BUFFER_SIZE] = {0};
DWORD dwSurplus = nfilesize % sizeof(bufFile);
while(true)
{
// Read File Data From Net.
BOOL bRead = InternetReadFile(hFile, bufFile, sizeof(bufFile), &dwBytesRead);
if(dwBytesRead == 0) // End of file.
break;
// Write file data.
WriteFile(hDownFile, bufFile, dwBytesRead, &dwWrite,NULL);
}
InternetCloseHandle(hFile) ;
InternetCloseHandle(hNet) ;
CloseHandle(hDownFile) ;
//OutputDebugString("/nCHttpDownload::UrlDownloadToFile() --.");
return true;
}
// Download URL contents to memory buffer.
// if pBuf == NULL, *pdwBufSize will contain the real size of remote size;
// *pdwBufSize alwayls contains the size of remote size.
bool CHttpDownload::UrlDownloadToBuffer(TCHAR *ptszURL, LPVOID pBuf, DWORD *pdwBufSize)
{
HINTERNET hNet;
HINTERNET hFile;
std::string sProxyServer;
DWORD dwStatusCode;
TCHAR dwStatusCode1[32] = {0};
DWORD dwSize1 = sizeof(dwStatusCode1), dwSize = sizeof(DWORD);
int nfilesize; // file size, 2GB limited. ;)
m_sUrl = ptszURL;
//OutputDebugString("/nCHttpDownload::UrlDownloadToFile() ++");
//
if(m_ConnectionType == UseProxy)
hNet = InternetOpen(tszAgent, INTERNET_OPEN_TYPE_PROXY, m_sProxy.c_str(), NULL, 0);
else if(m_ConnectionType == DirectToInternet)
hNet = InternetOpen(tszAgent, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
else if(m_ConnectionType == UsePreConfig)
hNet = InternetOpen(tszAgent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if(hNet == NULL)
{
//OutputDebugString("/nCHttpDownload::UrlDownloadToFile() --.1");
return false;
}
hFile = InternetOpenUrl(hNet, m_sUrl.c_str(), NULL, 0, 0, 0);
if(hFile == NULL)
{
InternetCloseHandle(hNet) ;
//OutputDebugString("/nCHttpDownload::UrlDownloadToFile() --.2");
return false;
}
BOOL bRet = HttpQueryInfo(hFile, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER,&dwStatusCode,&dwSize,NULL);
if(200 != dwStatusCode) // if URI is not exist, give up.
{
InternetCloseHandle(hNet) ;
InternetCloseHandle(hFile) ;
//OutputDebugString("/nCHttpDownload::UrlDownloadToFile() --.3");
return false;
}
if(HttpQueryInfo(hFile,HTTP_QUERY_CONTENT_LENGTH, &dwStatusCode1,&dwSize1,NULL))
{
nfilesize = atoi(dwStatusCode1); // file size.
}
char szBuffer[MAX_BUFFER_SIZE+1] = {0};
if(pBuf != NULL) // We only copy the 1st MAX_BUFFER_SIZE data to user buffer!!!
{
unsigned long nSize = 0;
BOOL bRet = InternetReadFile(hFile, szBuffer, MAX_BUFFER_SIZE, &nSize);
szBuffer[nSize] = '/0';
// dump buffer.
DWORD dwtSize = (*pdwBufSize > nSize)? nSize: *pdwBufSize;
memcpy(pBuf, szBuffer, dwtSize);
}
*pdwBufSize = nfilesize;
InternetCloseHandle(hFile) ;
InternetCloseHandle(hNet) ;
return true;
}[/code]
这点,Windows 自动更新发生过这样的问题:如果使用了 IE 代理,如果下载代码位于系统帐号
下,代理设置可能会失效。当然,也可以为系统帐号手动设置代理(其实就是 IE 的代理的设置
方法),不过,程序会受到很多的限制。
所以,可以考虑使用下属两个函数进行使用 - 服务程序亦可。^_^[code]//
// Download a file from the URL.
bool CHttpDownload::UrlDownloadToFile(TCHAR *ptszURL, TCHAR *ptszFilePath)
{
HINTERNET hNet;
HINTERNET hFile;
std::string sProxyServer;
DWORD dwStatusCode;
TCHAR dwStatusCode1[32] = {0};
DWORD dwSize1 = sizeof(dwStatusCode1), dwSize = sizeof(DWORD);
int nfilesize; // file size, 2GB limited. ;)
m_sUrl = ptszURL;
//OutputDebugString("/nCHttpDownload::UrlDownloadToFile() ++");
//
if(m_ConnectionType == UseProxy)
{
//OutputDebugString("/n ==> Useproxy");
hNet = InternetOpen(tszAgent, INTERNET_OPEN_TYPE_PROXY, m_sProxy.c_str(), NULL, 0);
}
else if(m_ConnectionType == DirectToInternet)
{
//OutputDebugString("/n ==> DirectToInternet");
hNet = InternetOpen(tszAgent, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
}
else if(m_ConnectionType == UsePreConfig)
{
//OutputDebugString("/n ==> UsePreConfig");
hNet = InternetOpen(tszAgent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
}
if(hNet == NULL)
{
//OutputDebugString("/nCHttpDownload::UrlDownloadToFile() --.1");
return false;
}
hFile = InternetOpenUrl(hNet, m_sUrl.c_str(), NULL, 0, 0, 0);
if(hFile == NULL)
{
InternetCloseHandle(hNet) ;
//OutputDebugString(m_sUrl.c_str());
//OutputDebugString(ptszURL);
//OutputDebugString("/nCHttpDownload::UrlDownloadToFile() --.2");
return false;
}
BOOL bRet = HttpQueryInfo(hFile, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER,&dwStatusCode,&dwSize,NULL);
if(200 != dwStatusCode) // if URI is not exist, give up.
{
InternetCloseHandle(hNet) ;
InternetCloseHandle(hFile) ;
//OutputDebugString("/nCHttpDownload::UrlDownloadToFile() --.3");
return false;
}
if(HttpQueryInfo(hFile,HTTP_QUERY_CONTENT_LENGTH, &dwStatusCode1,&dwSize1,NULL))
{
nfilesize = atoi(dwStatusCode1); // file size.
}
HANDLE hDownFile = CreateFile(ptszFilePath,
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if(INVALID_HANDLE_VALUE == hDownFile)
{
InternetCloseHandle(hNet) ;
InternetCloseHandle(hFile) ;
//OutputDebugString("/nCHttpDownload::UrlDownloadToFile() --.4");
return false;
}
// O.K. save file
DWORD dwWrite, dwBytesRead = 0;
char bufFile[MAX_BUFFER_SIZE] = {0};
DWORD dwSurplus = nfilesize % sizeof(bufFile);
while(true)
{
// Read File Data From Net.
BOOL bRead = InternetReadFile(hFile, bufFile, sizeof(bufFile), &dwBytesRead);
if(dwBytesRead == 0) // End of file.
break;
// Write file data.
WriteFile(hDownFile, bufFile, dwBytesRead, &dwWrite,NULL);
}
InternetCloseHandle(hFile) ;
InternetCloseHandle(hNet) ;
CloseHandle(hDownFile) ;
//OutputDebugString("/nCHttpDownload::UrlDownloadToFile() --.");
return true;
}
// Download URL contents to memory buffer.
// if pBuf == NULL, *pdwBufSize will contain the real size of remote size;
// *pdwBufSize alwayls contains the size of remote size.
bool CHttpDownload::UrlDownloadToBuffer(TCHAR *ptszURL, LPVOID pBuf, DWORD *pdwBufSize)
{
HINTERNET hNet;
HINTERNET hFile;
std::string sProxyServer;
DWORD dwStatusCode;
TCHAR dwStatusCode1[32] = {0};
DWORD dwSize1 = sizeof(dwStatusCode1), dwSize = sizeof(DWORD);
int nfilesize; // file size, 2GB limited. ;)
m_sUrl = ptszURL;
//OutputDebugString("/nCHttpDownload::UrlDownloadToFile() ++");
//
if(m_ConnectionType == UseProxy)
hNet = InternetOpen(tszAgent, INTERNET_OPEN_TYPE_PROXY, m_sProxy.c_str(), NULL, 0);
else if(m_ConnectionType == DirectToInternet)
hNet = InternetOpen(tszAgent, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
else if(m_ConnectionType == UsePreConfig)
hNet = InternetOpen(tszAgent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if(hNet == NULL)
{
//OutputDebugString("/nCHttpDownload::UrlDownloadToFile() --.1");
return false;
}
hFile = InternetOpenUrl(hNet, m_sUrl.c_str(), NULL, 0, 0, 0);
if(hFile == NULL)
{
InternetCloseHandle(hNet) ;
//OutputDebugString("/nCHttpDownload::UrlDownloadToFile() --.2");
return false;
}
BOOL bRet = HttpQueryInfo(hFile, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER,&dwStatusCode,&dwSize,NULL);
if(200 != dwStatusCode) // if URI is not exist, give up.
{
InternetCloseHandle(hNet) ;
InternetCloseHandle(hFile) ;
//OutputDebugString("/nCHttpDownload::UrlDownloadToFile() --.3");
return false;
}
if(HttpQueryInfo(hFile,HTTP_QUERY_CONTENT_LENGTH, &dwStatusCode1,&dwSize1,NULL))
{
nfilesize = atoi(dwStatusCode1); // file size.
}
char szBuffer[MAX_BUFFER_SIZE+1] = {0};
if(pBuf != NULL) // We only copy the 1st MAX_BUFFER_SIZE data to user buffer!!!
{
unsigned long nSize = 0;
BOOL bRet = InternetReadFile(hFile, szBuffer, MAX_BUFFER_SIZE, &nSize);
szBuffer[nSize] = '/0';
// dump buffer.
DWORD dwtSize = (*pdwBufSize > nSize)? nSize: *pdwBufSize;
memcpy(pBuf, szBuffer, dwtSize);
}
*pdwBufSize = nfilesize;
InternetCloseHandle(hFile) ;
InternetCloseHandle(hNet) ;
return true;
}[/code]
Using WinInet HTTP functions in Full Asynchronous Mode
[url]http://www.codeproject.com/internet/asyncwininet.asp[/url]
Offline Browser using WinInet, URL Moniker and MSHTML APIs
[url]http://www.codeproject.com/internet/OfflineBrowserWinInet.asp[/url]
Common HTTP and FTP WinInet APIs
[url]http://www.dotnetheaven.com/UploadFile/mahesh/CommonHTTPandFTP05242005075834AM/CommonHTTPandFTP.aspx[/url]
[url]http://topic.youkuaiyun.com/t/20050507/16/3987488.html[/url]
Discover WIN32. How to use a sync/async retrieve HTTP content in your ASP & VB projects.
[url]http://www.codeproject.com/internet/retrievehttp.asp[/url]
HTTP Proxy download
[url]http://www.vbforums.com/archive/index.php/t-225065.html[/url]
HTTP/FTP客户端开发库:libwww、libcurl、libfetch 以及更多
[url]http://blog.youkuaiyun.com/heiyeshuwu/archive/2007/07/15/1691904.aspx
[url]http://www.codeproject.com/internet/asyncwininet.asp[/url]
Offline Browser using WinInet, URL Moniker and MSHTML APIs
[url]http://www.codeproject.com/internet/OfflineBrowserWinInet.asp[/url]
Common HTTP and FTP WinInet APIs
[url]http://www.dotnetheaven.com/UploadFile/mahesh/CommonHTTPandFTP05242005075834AM/CommonHTTPandFTP.aspx[/url]
[url]http://topic.youkuaiyun.com/t/20050507/16/3987488.html[/url]
Discover WIN32. How to use a sync/async retrieve HTTP content in your ASP & VB projects.
[url]http://www.codeproject.com/internet/retrievehttp.asp[/url]
HTTP Proxy download
[url]http://www.vbforums.com/archive/index.php/t-225065.html[/url]
HTTP/FTP客户端开发库:libwww、libcurl、libfetch 以及更多
[url]http://blog.youkuaiyun.com/heiyeshuwu/archive/2007/07/15/1691904.aspx