Skip to main content.

Friday, December 15, 2006

WinInet APIの利用(その2)

WinInet APIの利用の続きになります。WinInet APIを利用して、HTTPプロトコルで、ファイルをダウンロードするテストプログラムです。今度は、VC++ 6.0のMFCのダイアログアプリケーションです。前回と同じようなプログラムですが、動きが分かりやすいと思います。


実行画面

ダウンロードするファイルのURLとローカルファイル名を指定して、ファイルをダウンロードします。WinInet APIを使っているのは、実行ボタンを押された時です。以下の処理をしています。

以下、プログラム
※2006/12/15 CInternetSessionのコンストラクタの間違いを修正しました。
------------------------------------------------------------------
void CWinInet2Dlg::OnExec()
{
    // TODO: この位置にコントロール通知ハンドラ用のコードを追加してください

    CWaitCursor cursor;  //砂時計
    UpdateData(TRUE);

    // ここからがHTTPの処理
    INTERNET_PORT nPort=0; //ポート番号
    DWORD dwServiceType=0; //サービスタイプ

    DWORD dwAccessType = PRE_CONFIG_INTERNET_ACCESS; //アクセスタイプ

    CString sObject="";
    CString sServerName="";

    //URLの解析
    AfxParseURL(m_sURL, dwServiceType, sServerName, sObject, nPort);

    //※2006/12/15 間違いがありましたので修正しました。
    //セッションの生成
    // CInternetSession session("Test Agent Ver0.01",dwAccessType);
    /*
    CInternetSessionのコンストラクタの定義は(※VC++ Ver6.0の場合)AfxInet.hには以下のようにあります。

    CInternetSession(LPCTSTR pstrAgent = NULL,
    DWORD dwContext = 1,
    DWORD dwAccessType = PRE_CONFIG_INTERNET_ACCESS,
    LPCTSTR pstrProxyName = NULL,
    LPCTSTR pstrProxyBypass = NULL,
    DWORD dwFlags = 0);
    */
    // dwAccessTypeまでを指定するのであれば、以下の様になります。
    DWORD dwContext = 1;
    CInternetSession session("Test Agent Ver0.01",dwContext,dwAccessType);
    // 2006/12/15修正ここまで


    //コネクションの確立
    CHttpConnection* pServerConn = session.GetHttpConnection(sServerName,nPort);

    //リクエストの送信
    int nverb = CHttpConnection::HTTP_VERB_GET;
    DWORD dwInetFlags = INTERNET_FLAG_EXISTING_CONNECT;

    CHttpFile* pFile = pServerConn->OpenRequest(nverb, sObject, NULL, 1, NULL, NULL, dwInetFlags);

    CString strHeaders =_T("Content-Type: application/x-www-form-urlencoded");
    pFile->AddRequestHeaders(strHeaders);

    pFile->SendRequest();

    DWORD dwRet;
    pFile->QueryInfoStatusCode(dwRet);

    //ステータスチェック
    if(dwRet >= HTTP_STATUS_BAD_REQUEST){
        m_sResult.Format("HTTPステータスエラー! %d",dwRet);
    }
    else{
        unsigned char buf[2048];
        
        //これよりファイルへの書き込み
        CFile fp;

        if(fp.Open(m_sFname,CFile::modeCreate|CFile::modeWrite) == NULL){
            m_sResult.Format("出力ファイルがオープンできません");
        }else{
            while(long len = pFile->Read(buf,2048)){
                fp.Write(buf,len);
            }
            fp.Close();
            m_sResult.Format("おそらく正常終了");
            }
        }
        UpdateData(FALSE);

        //後処理
        pFile->Close();
        pServerConn->Close();
        session.Close();

        delete pFile;
        delete pServerConn;
}
------------------------------------------------------------------------------
業務アプリケーション等で作成する場合、try{} charch{}でエラー処理をしてください。書き方については、例えばですが、以下の参考サイトを参考にしてください。キーワードは、CInternetExceptionです。

VC++ 6.0のプロジェクトファイルを以下に置きました。
プロジェクトファイル一式(※2006/12/15修正版)

Windows2000とXPで動作確認しましたが、エラー処理等、不十分ですので、動作は保証できません。このプログラムを利用しての不具合、不利益には一切の責任を負いかねます。ご了承ください。

参考サイト
HTTPでのファイルのダウンロード

MSDN WinInetの基礎
MSDN Win32 インターネット拡張機能 (WinInet)
MSDN CInternetSessionクラス(MFC)
MSDN CHttpConnectionクラス(MFC)
MSDN CHttpFileクラス(MFC)