[an error occurred while processing this directive] [an error occurred while processing this directive]

Wget-like プログラム (Webサーバのファイルをダウンロードするプログラム)

WinInet 版

MFC や .NET に頼らないで、なるべく一般的な API は... と探したら、Windows のソケット API に近い WinInet と呼ばれる一連の API があるようです。HINTERNET 構造体を識別子として、http や ftp の通信ができます。文字列はマルチバイト (CString系) ではなく、Unicode 文字セット (wstring 系) を使用しています。
[wget.cpp]
#include "stdafx.h"
#pragma comment(lib, "Wininet.lib")

const DWORD BUF_SIZE = 128 * 1024;
static bool wget(std::string &url, std::string &dest_fn){
    HINTERNET hInet = InternetOpen(NULL, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
    if(hInet == NULL){
        std::cerr << "Failed to open, lastErr = " << GetLastError() << std::endl;
        return false;
    }
    wchar_t *wcs = new wchar_t[url.length() * 2 + 1];
    mbstowcs(wcs, url.c_str(), url.length() + 1);
    HINTERNET hFile = InternetOpenUrl(hInet, wcs, NULL, 0, 0, 0);
    delete [] wcs;

    std::ofstream ofs(dest_fn);
    char buf[BUF_SIZE];
    for(;;){
        DWORD tmpSize;
        InternetReadFile(hFile, buf, BUF_SIZE, &tmpSize);
        if(tmpSize <= 0){
            break;
        }
        buf[tmpSize] = '\0';
        ofs << buf;
    }
    ofs.close();
    InternetCloseHandle(hInet);
    return true;
}


int main(int argc, char* argv[]){
    std::string url = "http://funini.com/kei/";
    std::string dest_fn = "hoge.txt";
    wget(url, dest_fn);
    return 0;
}
[stdafx.h]
#pragma once

#include "targetver.h"

#include <string>
#include <iostream>
#include <fstream>
#include <windows.h>
#include <Wininet.h>
実行すると、http://funini.com/kei/ が hoge.txt として保存されます。

MFC 版

http サーバ上のファイルをダウンロードする Windows プログラム(Win32)を書きたかったので調べてみたら、 MFCを使うのが簡単そうだから、そうしてみました。 動作としては、Windows版のWgetみたいな動作をするアプリを書いてみました。
/**
  * 指定されたURLのファイルを、指定されたファイル名で
  * ダウンロードする関数  @@ Kei Takahashi
  *
  * 返り値: ダウンロード成功(True)/失敗(False)
  * 使用例: 
  *  bool ret = download("funini.png","http://funini.com/imgs/funini.png");
  * 
  * 
  * - MFCプロジェクト上で使用して下さい
  * - stdafx.hで以下のようにヘッダファイルをincludeして下さい。
  * #include <afxinet.h>
  * 
  */


bool download(CString fn, CString url) {
	const int	BUF_LEN=1024;
	BYTE		lpBuff[BUF_LEN];

	// 接続を張って、リモートのファイルにアクセスできるようにする
	CInternetSession cSec(NULL, 1, INTERNET_OPEN_TYPE_PRECONFIG, NULL,NULL,0 );// # Use IE Settings
	CStdioFile* remoteFile = cSec.OpenURL(url, 1, INTERNET_FLAG_TRANSFER_BINARY|INTERNET_FLAG_RELOAD, NULL, 0);
	if(remoteFile == NULL) return false;

	// ローカルファイルを開いて、ダウンロード開始
	CStdioFile			localFile;
	localFile.Open(fn, CFile::modeCreate | CFile::modeWrite | CFile::shareDenyNone | CFile::typeBinary);
	for(;;){
		int n = remoteFile->Read(lpBuff, BUF_LEN);
		localFile.Write(lpBuff,n);
		if(n > BUF_LEN) break;
	}
	localFile.Close();

	// 後処理
	delete	remoteFile;
	return true;
}

はまった点いろいろ

[an error occurred while processing this directive]