Skip to main content.

(PR:株式会社インデペンデンスシステムズ横浜では、開発の御依頼をお待ちしております。)

Friday, December 15, 2006

WinInet APIの利用

WinInetとはWin32インターネット拡張機能で、実体は"Wininet.dll"です。WinInetはIE3.0以上がインストールされている環境で利用することができます。

このWinInetを利用すると、比較的簡単にHTTP、HTTPS、FTPといったプロトコルのアプリケーションを作成することが出来ます。汎用的なインターネットアプリケーションを作成する場合は、Windowsの場合、Winsockを利用すると思いますが、ファイル転送の自動化、ファイルダウンロードの自動化、あるいはブラウザで操作するフォームの処理の自動化といった比較的簡単なアプリケーションでは、WinInetで十分対応できると思います。私の場合も、いくつかのアプリケーションをWinInetで作成しました。

WinInetはAPI(関数)ですので、VC++、VBからも利用することが出来ます。VC++の場合、MFCのクラスからも利用出来ます。私の場合は、このMFCのクラスを利用して作成しました。

ここでは、MFCを利用した簡単なプログラムを紹介します。VC++ Ver6.0でのコンソールアプリケーションです。このプログラムは、http://www.independence-sys.com/index.htmlをGETして、コンソールに表示するプログラムです。
(※ MFCのダイアログアプリケーション版はこちらです。)

※2006/12/15 CInternetSessionのコンストラクタの間違いを修正しました。

以下、プログラム
------------------------------------------------------------------
#include "stdafx.h"
#include "winInet.h"

//MFCの場合このインクルードが必要です
#include < afxinet.h >

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define BUFSIZE 2048

CWinApp theApp;
using namespace std;

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
    int nRetCode = 0;

    // MFC の初期化および初期化失敗時のエラーの出力
    if(!AfxWinInit(::GetModuleHandle(NULL),NULL, ::GetCommandLine(), 0))
    {
       cerr << _T("Fatal Error: MFC initialization failed") << endl;
       nRetCode = 1;
       return nRetCode;
    }

    // ここからがHTTPの処理
    CString sURL; //取得するURL
    CString sServerName; //サーバ名
    CString sObject; //取得するオブジェクト名
    INTERNET_PORT nPort=0; //ポート番号
    DWORD dwServiceType=0; //サービスタイプ
    DWORD dwAccessType = PRE_CONFIG_INTERNET_ACCESS; //アクセスタイプ

    //サーバ名とオブジェクト名の設定
    //実行する場合は、適当に変更してください
    //sURL = "http://www.independence-sys.com";
    //sObject = "index.html";
    //※8月16日修正
    //ここは以下のようにするのが正しいです。
    sURL = "http://www.independence-sys.com/index.html";
    sObject = "";

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

    //セッションの生成
    //Webサーバのログには、
    //"Test Agent Ver0.01"というブラウザからのアクセスとして残ります
    
    //※2006/12/15 間違いがありましたので、修正しました。dwAccessTypeは3番目です
    //セッションの生成
    // 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){
        printf("HTTP Error %d!\n",dwRet);
        nRetCode = -1;
    }
    else{
        //コンテンツの読み込み
        CString sBuf;
        //※8月16日修正
        //ここでReadを使うと表示が正しくされません。ReadString()に修正しました。
        //while(long len = pFile->Read(sBuf.GetBuffer(0),BUFSIZE)){
        //    printf("%s\n",sBuf);
        //}
        while(pFile->ReadString(sBuf.GetBuffer(0),BUFSIZE)){
            printf("%s\n",sBuf);
        }
    }
    //後処理
    pFile->Close();
    pServerConn->Close();
    session.Close();

    delete pFile;
    delete pServerConn;

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

(※エラー処理等、不十分ですので、動作は保証できません。このプログラムを利用しての不具合、不利益には一切の責任を負いかねます。)

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