以下使用 WinINet function 來實現 WebRequest 的功能
55 // Example: 56 // WebRequest(_T("http://www.google.com.tw")); 57 // WebRequest(_T("http://www.google.com.tw"), _T("google2.txt")); 58 // |
提供兩種方式呼叫,一種是將 HTML 輸出在 Console,
另一種是除了輸出到 Console,還會輸出到檔案
如果在編譯時,Preprocessor 有設定 UNICODE,則 TCHAR 就會使用 wchar_t,不然就會用 char
所以在輸出在 Console、或是輸出到檔案希望支援 UNICODE,字碼不會變亂碼,就請加上 UNICODE
在 WebRequest 執行到最後,會統計 HTML 的長度並輸出到 Console
302 printf("\nLength: %d\n", Length);
|
以及最後會 WebRequest 會 Return 一個 bool,代表執行成功、或是失敗
319 return IsSuccess;
|
若中間有任何失敗,會呼叫 ErrorNonExit() 輸出錯誤訊息
1 #include <stdlib.h>
2 #include <tchar.h> 3 #include <windows.h> 4 #include <wininet.h> 5 #pragma comment(lib, "wininet.lib") 6 7 #include <strsafe.h> 8 9 // http://msdn.microsoft.com/en-us/library/ms680582%28v=VS.85%29.aspx 10 // Example: 11 // ErrorNonExit(L"FunName"); 12 // 13 DWORD ErrorNonExit(LPTSTR lpszFunction) { 14 // Retrieve the system error message for the last-error code 15 LPVOID lpMsgBuf; 16 LPVOID lpDisplayBuf; 17 DWORD dw = GetLastError(); 18 19 FormatMessage( 20 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 21 NULL, 22 dw, 23 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 24 (LPTSTR) &lpMsgBuf, 25 0, 26 NULL); 27 28 // Display the error message and exit the process 29 lpDisplayBuf = (LPVOID)LocalAlloc( 30 LMEM_ZEROINIT, 31 (lstrlen((LPTSTR)lpMsgBuf) + lstrlen((LPTSTR)lpszFunction) + 40) * sizeof(LPTSTR) 32 ); 33 34 printf("%S failed with error %d", lpszFunction, dw); 35 36 char lpError[MAX_PATH] = ""; 37 WideCharToMultiByte(CP_ACP, 0, (LPTSTR)lpMsgBuf, -1, lpError, MAX_PATH, NULL, NULL); 38 39 if (lpError[0] != '\0') { 40 printf(": %s\n", lpError); 41 } else { 42 puts(""); 43 } 44 45 LocalFree(lpMsgBuf); 46 LocalFree(lpDisplayBuf); 47 48 return dw; 49 } 50 51 void ErrorExit(LPTSTR lpszFunction) { 52 ExitProcess(ErrorNonExit(lpszFunction)); 53 } 54 55 // Example: 56 // WebRequest(_T("http://www.google.com.tw")); 57 // WebRequest(_T("http://www.google.com.tw"), _T("google2.txt")); 58 // 59 bool WebRequest(const TCHAR *URL, const TCHAR *OutputFileName = _T("")) { 60 bool IsSuccess = false; 61 62 HINTERNET hSession = NULL; 63 HINTERNET hConnect = NULL; 64 HINTERNET hRequest = NULL; 65 FILE *outFile = NULL; 66 67 // InternetOpen Function 68 // Initializes an application's use of the WinINet functions. 69 // 70 // HINTERNET InternetOpen( 71 // __in LPCTSTR lpszAgent, 72 // __in DWORD dwAccessType, 73 // __in LPCTSTR lpszProxyName, 74 // __in LPCTSTR lpszProxyBypass, 75 // __in DWORD dwFlags 76 // ); 77 // 78 // http://msdn.microsoft.com/en-us/library/aa385096%28v=VS.85%29.aspx 79 // 80 // Parameters 81 // LPCTSTR lpszAgent [in] 82 // Pointer to a null-terminated string that specifies the name 83 // of the application or entity calling the WinINet functions. 84 // This name is used as the user agent in the HTTP protocol. 85 // 86 // DWORD dwAccessType [in] 87 // INTERNET_OPEN_TYPE_DIRECT: 88 // Resolves all host names locally. 89 // 90 // INTERNET_OPEN_TYPE_PRECONFIG: 91 // Retrieves the proxy or direct configuration from the 92 // registry. 93 // 94 // INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY: 95 // Retrieves the proxy or direct configuration from the 96 // registry and prevents the use of a startup Microsoft 97 // JScript or Internet Setup (INS) file. 98 // 99 // INTERNET_OPEN_TYPE_PROXY: 100 // Passes requests to the proxy unless a proxy bypass list 101 // is supplied and the name to be resolved bypasses the proxy. 102 // In this case, the function uses INTERNET_OPEN_TYPE_DIRECT. 103 // 104 // LPCTSTR lpszProxyName [in] 105 // Pointer to a null-terminated string that specifies the name 106 // of the proxy server(s) to use when proxy access is specified 107 // by setting dwAccessType to INTERNET_OPEN_TYPE_PROXY. 108 // 109 // Do not use an empty string, because InternetOpen will use it 110 // as the proxy name. The WinINet functions recognize only CERN 111 // type proxies (HTTP only) and the TIS FTP gateway (FTP only). 112 // 113 // If Microsoft Internet Explorer is installed, these functions 114 // also support SOCKS proxies. FTP requests can be made through 115 // a CERN type proxy either by changing them to an HTTP request 116 // or by using InternetOpenUrl. If dwAccessType is not set to 117 // INTERNET_OPEN_TYPE_PROXY, this parameter is ignored and should 118 // be NULL. For more information about listing proxy servers, see 119 // the Listing Proxy Servers section of Enabling Internet 120 // Functionality. 121 // 122 // LPCTSTR lpszProxyBypass [in] 123 // Pointer to a null-terminated string that specifies an optional 124 // list of host names or IP addresses, or both, that should not 125 // be routed through the proxy when dwAccessType is set to 126 // INTERNET_OPEN_TYPE_PROXY. The list can contain wildcards. 127 // 128 // Do not use an empty string, because InternetOpen will use it 129 // as the proxy bypass list. If this parameter specifies the 130 // "<local>" macro as the only entry, the function bypasses any 131 // host name that does not contain a period. If dwAccessType is 132 // not set to INTERNET_OPEN_TYPE_PROXY, this parameter is ignored 133 // and should be NULL. 134 // 135 // DWORD dwFlags [in] 136 // INTERNET_FLAG_ASYNC: 137 // Makes only asynchronous requests on handles descended from 138 // the handle returned from this function. 139 // 140 // INTERNET_FLAG_FROM_CACHE: 141 // Does not make network requests. All entities are returned 142 // from the cache. 143 // 144 // If the requested item is not in the cache, a suitable error, 145 // such as ERROR_FILE_NOT_FOUND, is returned. 146 // 147 // INTERNET_FLAG_OFFLINE: Identical to INTERNET_FLAG_FROM_CACHE. 148 // Does not make network requests. All entities are returned 149 // from the cache. 150 // 151 // If the requested item is not in the cache, a suitable error, 152 // such as ERROR_FILE_NOT_FOUND, is returned. 153 // 154 // Return Value 155 // Returns a valid handle that the application passes to subsequent 156 // WinINet functions. If InternetOpen fails, it returns NULL. To 157 // retrieve a specific error message, call GetLastError. 158 // 159 // Minimum supported client: Windows 2000 Professional 160 // Minimum supported server: Windows 2000 Server 161 // 162 hSession=InternetOpen( 163 _T("Mozilla/4.0 (compatible; MSIE 8.0; Win32)"), 164 INTERNET_OPEN_TYPE_PRECONFIG, 165 NULL, 166 NULL, 167 NULL); 168 169 if (hSession == NULL) { 170 ErrorNonExit(L"InternetOpen"); 171 goto cleanup; 172 } 173 174 // InternetOpenUrl Function 175 // Opens a resource specified by a complete FTP or HTTP URL. 176 // 177 // HINTERNET InternetOpenUrl( 178 // __in HINTERNET hInternet, 179 // __in LPCTSTR lpszUrl, 180 // __in LPCTSTR lpszHeaders, 181 // __in DWORD dwHeadersLength, 182 // __in DWORD dwFlags, 183 // __in DWORD_PTR dwContext 184 // ); 185 // 186 // http://msdn.microsoft.com/en-us/library/aa385098%28VS.85%29.aspx 187 // 188 // Parameters 189 // HINTERNET hInternet [in] 190 // The handle to the current Internet session. The handle must 191 // have been returned by a previous call to InternetOpen. 192 // 193 // LPCTSTR lpszUrl [in] 194 // A pointer to a null-terminated string variable that specifies 195 // the URL to begin reading. Only URLs beginning with ftp:, http:, 196 // or https: are supported. 197 // 198 // LPCTSTR lpszHeaders [in] 199 // A pointer to a null-terminated string that specifies the 200 // headers to be sent to the HTTP server. For more information, 201 // see the description of the lpszHeaders parameter in the 202 // HttpSendRequest function. 203 // 204 // DWORD dwHeadersLength [in] 205 // The size of the additional headers, in TCHARs. If this 206 // parameter is -1L and lpszHeaders is not NULL, lpszHeaders is 207 // assumed to be zero-terminated (ASCIIZ) and the length is 208 // calculated. 209 // 210 // DWORD dwFlags [in] 211 // 212 // DWORD_PTR dwContext [in] 213 // A pointer to a variable that specifies the application-defined 214 // value that is passed, along with the returned handle, to any 215 // callback functions. 216 // 217 // Return Value 218 // Returns a valid handle to the URL if the connection is successfully 219 // established, or NULL if the connection fails. To retrieve a 220 // specific error message, call GetLastError. To determine why access 221 // to the service was denied, call InternetGetLastResponseInfo. 222 // 223 hConnect = InternetOpenUrl( 224 hSession, 225 URL, 226 NULL, 227 0, 228 INTERNET_FLAG_RELOAD, 229 0); 230 231 if (hConnect == NULL) { 232 ErrorNonExit(_T("InternetOpenUrl")); 233 goto cleanup; 234 } 235 236 DWORD dwSize; 237 char szBuffer[100]; 238 TCHAR tszBuffer[101]; 239 240 SecureZeroMemory(szBuffer, sizeof(szBuffer)); 241 SecureZeroMemory(tszBuffer, sizeof(tszBuffer)); 242 243 if (OutputFileName[0] != '\0') { 244 outFile = _tfopen(OutputFileName, _T("w")); 245 } 246 247 unsigned int Length = 0; 248 while (true) { 249 // InternetReadFile Function 250 // Reads data from a handle opened by the InternetOpenUrl, 251 // FtpOpenFile, or HttpOpenRequest function. 252 // 253 // BOOL InternetReadFile( 254 // __in HINTERNET hFile, 255 // __out LPVOID lpBuffer, 256 // __in DWORD dwNumberOfBytesToRead, 257 // __out LPDWORD lpdwNumberOfBytesRead 258 // ); 259 // 260 // http://msdn.microsoft.com/en-us/library/aa385103%28v=VS.85%29.aspx 261 // 262 // Parameters 263 // HINTERNET hFile [in] 264 // Handle returned from a previous call to InternetOpenUrl, 265 // FtpOpenFile, or HttpOpenRequest. 266 // 267 // LPVOID lpBuffer [out] 268 // Pointer to a buffer that receives the data. 269 // 270 // DWORD dwNumberOfBytesToRead [in] 271 // Number of bytes to be read. 272 // 273 // LPDWORD lpdwNumberOfBytesRead [out] 274 // Pointer to a variable that receives the number of bytes 275 // read. InternetReadFile sets this value to zero before doing 276 // any work or error checking. 277 // 278 // Return Value 279 // Returns TRUE if successful, or FALSE otherwise. To get extended 280 // error information, call GetLastError. An application can also 281 // use InternetGetLastResponseInfo when necessary. 282 // 283 if (!InternetReadFile (hConnect, szBuffer, sizeof(szBuffer), &dwSize) ) { 284 ErrorNonExit(L"InternetReadFile"); 285 goto cleanup; 286 } 287 if (dwSize <= 0) { 288 break; 289 } 290 291 Length += dwSize; 292 293 mbstowcs(tszBuffer, szBuffer, dwSize); 294 tszBuffer[dwSize] = 0; 295 _tprintf(_T("%s"), tszBuffer); 296 297 if (outFile != NULL) { 298 _ftprintf(outFile, _T("%s"), tszBuffer); 299 } 300 } 301 302 printf("\nLength: %d\n", Length); 303 304 IsSuccess = true; 305 306 cleanup: 307 if (outFile != NULL) { 308 fclose(outFile); 309 } 310 311 if (hConnect != NULL) { 312 InternetCloseHandle(hConnect); 313 } 314 315 if (hSession != NULL) { 316 InternetCloseHandle(hSession); 317 } 318 319 return IsSuccess; 320 } 321 322 int main(void) { 323 bool RequestState = WebRequest(_T("http://www.google.com.tw")); 324 325 printf("\nResult: "); 326 puts(RequestState ? "true" : "false"); 327 328 return 0; 329 } |
#include <stdlib.h> #include <tchar.h> #include <windows.h> #include <wininet.h> #pragma comment(lib, "wininet.lib") #include <strsafe.h> // http://msdn.microsoft.com/en-us/library/ms680582%28v=VS.85%29.aspx // Example: // ErrorNonExit(L"FunName"); // DWORD ErrorNonExit(LPTSTR lpszFunction) { // Retrieve the system error message for the last-error code LPVOID lpMsgBuf; LPVOID lpDisplayBuf; DWORD dw = GetLastError(); FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL); // Display the error message and exit the process lpDisplayBuf = (LPVOID)LocalAlloc( LMEM_ZEROINIT, (lstrlen((LPTSTR)lpMsgBuf) + lstrlen((LPTSTR)lpszFunction) + 40) * sizeof(LPTSTR) ); printf("%S failed with error %d", lpszFunction, dw); char lpError[MAX_PATH] = ""; WideCharToMultiByte(CP_ACP, 0, (LPTSTR)lpMsgBuf, -1, lpError, MAX_PATH, NULL, NULL); if (lpError[0] != '\0') { printf(": %s\n", lpError); } else { puts(""); } LocalFree(lpMsgBuf); LocalFree(lpDisplayBuf); return dw; } void ErrorExit(LPTSTR lpszFunction) { ExitProcess(ErrorNonExit(lpszFunction)); } // Example: // WebRequest(_T("http://www.google.com.tw")); // WebRequest(_T("http://www.google.com.tw"), _T("google2.txt")); // bool WebRequest(const TCHAR *URL, const TCHAR *OutputFileName = _T("")) { bool IsSuccess = false; HINTERNET hSession = NULL; HINTERNET hConnect = NULL; HINTERNET hRequest = NULL; FILE *outFile = NULL; // InternetOpen Function // Initializes an application's use of the WinINet functions. // // HINTERNET InternetOpen( // __in LPCTSTR lpszAgent, // __in DWORD dwAccessType, // __in LPCTSTR lpszProxyName, // __in LPCTSTR lpszProxyBypass, // __in DWORD dwFlags // ); // // http://msdn.microsoft.com/en-us/library/aa385096%28v=VS.85%29.aspx // // Parameters // LPCTSTR lpszAgent [in] // Pointer to a null-terminated string that specifies the name // of the application or entity calling the WinINet functions. // This name is used as the user agent in the HTTP protocol. // // DWORD dwAccessType [in] // INTERNET_OPEN_TYPE_DIRECT: // Resolves all host names locally. // // INTERNET_OPEN_TYPE_PRECONFIG: // Retrieves the proxy or direct configuration from the // registry. // // INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY: // Retrieves the proxy or direct configuration from the // registry and prevents the use of a startup Microsoft // JScript or Internet Setup (INS) file. // // INTERNET_OPEN_TYPE_PROXY: // Passes requests to the proxy unless a proxy bypass list // is supplied and the name to be resolved bypasses the proxy. // In this case, the function uses INTERNET_OPEN_TYPE_DIRECT. // // LPCTSTR lpszProxyName [in] // Pointer to a null-terminated string that specifies the name // of the proxy server(s) to use when proxy access is specified // by setting dwAccessType to INTERNET_OPEN_TYPE_PROXY. // // Do not use an empty string, because InternetOpen will use it // as the proxy name. The WinINet functions recognize only CERN // type proxies (HTTP only) and the TIS FTP gateway (FTP only). // // If Microsoft Internet Explorer is installed, these functions // also support SOCKS proxies. FTP requests can be made through // a CERN type proxy either by changing them to an HTTP request // or by using InternetOpenUrl. If dwAccessType is not set to // INTERNET_OPEN_TYPE_PROXY, this parameter is ignored and should // be NULL. For more information about listing proxy servers, see // the Listing Proxy Servers section of Enabling Internet // Functionality. // // LPCTSTR lpszProxyBypass [in] // Pointer to a null-terminated string that specifies an optional // list of host names or IP addresses, or both, that should not // be routed through the proxy when dwAccessType is set to // INTERNET_OPEN_TYPE_PROXY. The list can contain wildcards. // // Do not use an empty string, because InternetOpen will use it // as the proxy bypass list. If this parameter specifies the // "<local>" macro as the only entry, the function bypasses any // host name that does not contain a period. If dwAccessType is // not set to INTERNET_OPEN_TYPE_PROXY, this parameter is ignored // and should be NULL. // // DWORD dwFlags [in] // INTERNET_FLAG_ASYNC: // Makes only asynchronous requests on handles descended from // the handle returned from this function. // // INTERNET_FLAG_FROM_CACHE: // Does not make network requests. All entities are returned // from the cache. // // If the requested item is not in the cache, a suitable error, // such as ERROR_FILE_NOT_FOUND, is returned. // // INTERNET_FLAG_OFFLINE: Identical to INTERNET_FLAG_FROM_CACHE. // Does not make network requests. All entities are returned // from the cache. // // If the requested item is not in the cache, a suitable error, // such as ERROR_FILE_NOT_FOUND, is returned. // // Return Value // Returns a valid handle that the application passes to subsequent // WinINet functions. If InternetOpen fails, it returns NULL. To // retrieve a specific error message, call GetLastError. // // Minimum supported client: Windows 2000 Professional // Minimum supported server: Windows 2000 Server // hSession=InternetOpen( _T("Mozilla/4.0 (compatible; MSIE 8.0; Win32)"), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, NULL); if (hSession == NULL) { ErrorNonExit(L"InternetOpen"); goto cleanup; } // InternetOpenUrl Function // Opens a resource specified by a complete FTP or HTTP URL. // // HINTERNET InternetOpenUrl( // __in HINTERNET hInternet, // __in LPCTSTR lpszUrl, // __in LPCTSTR lpszHeaders, // __in DWORD dwHeadersLength, // __in DWORD dwFlags, // __in DWORD_PTR dwContext // ); // // http://msdn.microsoft.com/en-us/library/aa385098%28VS.85%29.aspx // // Parameters // HINTERNET hInternet [in] // The handle to the current Internet session. The handle must // have been returned by a previous call to InternetOpen. // // LPCTSTR lpszUrl [in] // A pointer to a null-terminated string variable that specifies // the URL to begin reading. Only URLs beginning with ftp:, http:, // or https: are supported. // // LPCTSTR lpszHeaders [in] // A pointer to a null-terminated string that specifies the // headers to be sent to the HTTP server. For more information, // see the description of the lpszHeaders parameter in the // HttpSendRequest function. // // DWORD dwHeadersLength [in] // The size of the additional headers, in TCHARs. If this // parameter is -1L and lpszHeaders is not NULL, lpszHeaders is // assumed to be zero-terminated (ASCIIZ) and the length is // calculated. // // DWORD dwFlags [in] // // DWORD_PTR dwContext [in] // A pointer to a variable that specifies the application-defined // value that is passed, along with the returned handle, to any // callback functions. // // Return Value // Returns a valid handle to the URL if the connection is successfully // established, or NULL if the connection fails. To retrieve a // specific error message, call GetLastError. To determine why access // to the service was denied, call InternetGetLastResponseInfo. // hConnect = InternetOpenUrl( hSession, URL, NULL, 0, INTERNET_FLAG_RELOAD, 0); if (hConnect == NULL) { ErrorNonExit(_T("InternetOpenUrl")); goto cleanup; } DWORD dwSize; char szBuffer[100]; TCHAR tszBuffer[101]; SecureZeroMemory(szBuffer, sizeof(szBuffer)); SecureZeroMemory(tszBuffer, sizeof(tszBuffer)); if (OutputFileName[0] != '\0') { outFile = _tfopen(OutputFileName, _T("w")); } unsigned int Length = 0; while (true) { // InternetReadFile Function // Reads data from a handle opened by the InternetOpenUrl, // FtpOpenFile, or HttpOpenRequest function. // // BOOL InternetReadFile( // __in HINTERNET hFile, // __out LPVOID lpBuffer, // __in DWORD dwNumberOfBytesToRead, // __out LPDWORD lpdwNumberOfBytesRead // ); // // http://msdn.microsoft.com/en-us/library/aa385103%28v=VS.85%29.aspx // // Parameters // HINTERNET hFile [in] // Handle returned from a previous call to InternetOpenUrl, // FtpOpenFile, or HttpOpenRequest. // // LPVOID lpBuffer [out] // Pointer to a buffer that receives the data. // // DWORD dwNumberOfBytesToRead [in] // Number of bytes to be read. // // LPDWORD lpdwNumberOfBytesRead [out] // Pointer to a variable that receives the number of bytes // read. InternetReadFile sets this value to zero before doing // any work or error checking. // // Return Value // Returns TRUE if successful, or FALSE otherwise. To get extended // error information, call GetLastError. An application can also // use InternetGetLastResponseInfo when necessary. // if (!InternetReadFile (hConnect, szBuffer, sizeof(szBuffer), &dwSize) ) { ErrorNonExit(L"InternetReadFile"); goto cleanup; } if (dwSize <= 0) { break; } Length += dwSize; mbstowcs(tszBuffer, szBuffer, dwSize); tszBuffer[dwSize] = 0; _tprintf(_T("%s"), tszBuffer); if (outFile != NULL) { _ftprintf(outFile, _T("%s"), tszBuffer); } } printf("\nLength: %d\n", Length); IsSuccess = true; cleanup: if (outFile != NULL) { fclose(outFile); } if (hConnect != NULL) { InternetCloseHandle(hConnect); } if (hSession != NULL) { InternetCloseHandle(hSession); } return IsSuccess; } int main(void) { bool RequestState = WebRequest(_T("http://www.google.com.tw")); printf("\nResult: "); puts(RequestState ? "true" : "false"); return 0; } |
沒有留言:
張貼留言