Reach the Specific URL and Download Files via MFC and Internet Explorer API 博客分类: MFC
Recently I was working on a small project to provide a convevient way for my colleagues to use a service hosted on a server. In linux platform, we can use curl/wget. What about the windows platform?
There are two ways, one is to use MFC API, another is to use Internet Explorer API.
1. MFC API
CInternetSession hSession; CString szRand; szRand.Format(_T("&t=%d"),GetTickCount()); CString szUrl("http://xxx.com/~zhanghechuan/netprecompile?branch=" + szVersion + szRand); CStdioFile* pResp = hSession.OpenURL((LPCTSTR)szUrl); CString szResp; pResp->ReadString(szResp); // write this line to a file
Code above shows the correct way to do such thing. CInternetSession class provides OpenURL method, which take the target url as the first parameter and return the respond as CStdioFile*. Notice that, the url must start with http://, ftp:// etc. For more Detail, check MSDN .
Since we have the respond, a CStdioFile*, we can read lines from it, and write lines to a local file via another CStdioFile handler.
However, when using this approach, you may get an assertion failure when running, while compiling and linking proccesses are without error. To solve this problem, you need to do as follows:
- Include afxwin.h.
- Declare a global CWinApp class variable.
- Add code below in the body of your main function.
if(!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0)){ return 1; }
2. IE API
An alternative is using IE API.
CString szArchive("http://xxx.com:8001/pm_templates/compile/52/compiled_template.tar.gz"); szRand.Format(_T("?t=%d"),GetTickCount()); szArchive += szRand; char* pComTplt = "compile/compiled_template.tar.gz"; URLDownloadToFile(NULL, (LPCTSTR)szArchive, pComTplt, 0, NULL);
Simple, isn't it? URLDownloadToFile takes the url as the second paramter and the local file which you wanna respond be written in as the third parameter(MSDN ). It's just like download files through a IE browser.
You may notice that, I add a timestamp for the url. That's because IE will cache the respond after first access it. Adding a timestamp forces IE to reaccess the url instead of reading from its cache.
However, there is a timeout bug in the afxinet package(http://support.microsoft.com/kb/q176420 ). When network condition is bad or the request service needs much time to fulfill, Using afxinet package could make your application crash. The alternative solution is using IE API which is heavier and less flexible.