SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

特集記事

各ブラウザのproxyサーバ情報を読み出して利用する

Internet Explorer、Firefox、Operaの設定情報を取得する


各ブラウザのproxyサーバ情報を読み出して利用する方法(2/2)

Operaの場合

 Operaの設定情報は、レジストリと設定ファイルの両方に分散して存在しています。proxyサーバに関する情報は、通常「OperaDef6.ini」または「opera6.ini」という名前のファイルに格納されています。

 このファイルがどこに置かれているかを判断するのに、レジストリや環境変数に設定されている情報を利用します。

 まず、レジストリ

HKEY_CURRENT_USER\Software\Opera Software

 が存在するかどうかを調べます。このレジストリが存在すれば、Operaがインストール済みであることが分かります。

 次に、上記レジストリからキーLast Directory2またはLast Directory3の値を取得します。値を取得できない場合は、Plugin Pathの値を取得します。この値も取得できなかった場合は、Last CommandLine v2の値を取得します。

 上記で取得したキーの値から、Operaのインストール先ディレクトリ名を取り出します。そして、Operaのインストール先ディレクトリに「OperaDef6.ini」というファイルがあれば、このファイルから次のような行を取り出します。

HTTP Server=proxyサーバ名:ポート番号

 Operaのバージョンが6.x~8.xのいずれかであれば、上記の方法で、「proxyサーバ名」と「ポート番号」を得ることができます。

 上記の方法で「proxyサーバ名」と「ポート番号」が得られなかった場合(Opera 9.x以降の場合)は、環境変数USERPROFILEの指すディレクトリ直下の

Application Data\Opera\Opera\profile

 というサブディレクトリに「opera6.ini」というファイルがありますので、このファイルから

HTTP server=proxyサーバ名:ポート番号

 という行を取り出します。この行が存在しない場合は、proxyサーバを使用しない設定でOperaを使っていることになります。

Operaの設定情報からproxy関連情報を取得する処理の例

 上記のことを踏まえ、「Operaの設定情報からproxy関連情報を取得する」処理を書いてみた例を、以下に示します(Cで記述しています)。

処理本体

 以下の処理例では、readProxySettingFromOperaIni()という関数を別途用意して、Operaの設定ファイル(「OperaDef6.ini」または「opera6.ini」形式のファイル)からproxy関連情報を取得しています。

Operaの設定情報からproxy関連情報を取得する
/*
 *  Opera の設定情報から、proxy関連情報を取得する
 *      -- 処理本体
 */
BOOL
getProxyInfoViaOpera(
        BOOL           *useProxy,   /* (O) proxy を使っているか否か */
        char           *proxyServer,/* (O) proxy サーバ名           */
        unsigned short *proxyPort,  /* (O) proxy ポート番号         */
        BOOL           verbose      /* (I) verbose モード           */
    )
{
    /* 手順                                                               */
    /*  (1) レジストリ                                                    */
    /*        HKEY_CURRENT_USER\Software\Opera Software                   */
    /*      が存在すれば、Opera インストール済み                          */
    /*  (2) 上記レジストリから キー                                       */
    /*        Last Directory2                                             */
    /*      の値を取得 (Last Directory2 の値が取れなかった場合は          */
    /*      Last Directory3 の値を取得)                                   */
    /*  (3) Last Directory2 も Last Directory3 も取れなかった場合は       */
    /*        Plugin Path                                                 */
    /*      の値を取得 (Plugin Path の値が取れなかった場合は              */
    /*      Last CommandLine v2 の値を取得)                               */
    /*  (4) 上記 (2) または (3) で得た情報から Opera のインストール先ディ */
    /*      レクトリがどこか判断                                          */
    /*  (5) Opera のインストール先ディレクトリにある OperaDef6.ini という */
    /*      ファイルの中に                                                */
    /*         HTTP Server=proxyサーバ名:ポート番号                       */
    /*      という記述があれば、proxy を使用する (Opera 6 ~ 8)           */
    /*  (6) 環境変数 USERPROFILE の指すディレクトリ以下の                 */
    /*      Application Data/Opera/Opera/profile/opera6.ini というファイ  */
    /*      ルの中に                                                      */
    /*         HTTP server=proxyサーバ名:ポート番号                       */
    /*      という記述があれば、proxy を使用する (Opera 9)                */

    long    ret;
    HKEY    hk;
    long    type;
    long    sz = BUFSIZ - 1;
    char    buf[BUFSIZ];
    char    *p;
    BOOL    isOperaActive = FALSE;

    ret = RegOpenKeyEx( HKEY_CURRENT_USER,
                        "Software\\Opera Software",
                        0,
                        KEY_READ,
                        &hk );
    if ( ret == ERROR_SUCCESS ) {
        ret = RegQueryValueEx( hk,
                               "Last Directory2",
                               NULL,
                               (unsigned long *)&type,
                               (unsigned char *)buf,
                               (unsigned long *)&sz );
        if ( ret != ERROR_SUCCESS )
            ret = RegQueryValueEx( hk,
                                   "Last Directory3",
                                   NULL,
                                   (unsigned long *)&type,
                                   (unsigned char *)buf,
                                   (unsigned long *)&sz );
                        // ↑↑↑ 通常はこれが hit する (Opera 6 以降) ↑↑↑
        if ( ret != ERROR_SUCCESS ) {
            ret = RegQueryValueEx( hk,
                                   "Plugin Path",
                                   NULL,
                                   (unsigned long *)&type,
                                   (unsigned char *)buf,
                                   (unsigned long *)&sz );
            if ( ret == ERROR_SUCCESS ) {
                p = strstr( buf, "\\\\Program\\\\Plugins" );
                if ( p && *p )
                    *p = '\0';
            }
        }
        if ( ret != ERROR_SUCCESS ) {
            // for Opera 9
            ret = RegQueryValueEx( hk,
                                   "Last CommandLine v2",
                                   NULL,
                                   (unsigned long *)&type,
                                   (unsigned char *)buf,
                                   (unsigned long *)&sz );
            if ( ret == ERROR_SUCCESS ) {
                p = strstr( buf, "\\\\Opera.exe" );
                if ( p && *p )
                    *p = '\0';
            }
        }
        if ( ret == ERROR_SUCCESS ) {
            /* Opera インストール済みであると判断 */
            isOperaActive = TRUE;
        }
        RegCloseKey( hk );
    }

    if ( isOperaActive == TRUE ) {
        BOOL    found = FALSE;
        char    filename[MAX_PATH];

        sprintf( filename, "%s\\OperaDef6.ini", buf );

        found = readProxySettingFromOperaIni( filename,
                                              useProxy,
                                              proxyServer, proxyPort,
                                              verbose );
        if ( found == FALSE ) {
            // for Opera 9
            char    *p = getenv( "USERPROFILE" );

            if ( p && *p ) {
                char    targetDir[MAX_PATH];

                sprintf( targetDir,
                         "%s\\Application Data\\Opera\\Opera\\profile\\", p );
                sprintf( filename, "%sopera6.ini", targetDir );
                found = readProxySettingFromOperaIni( filename,
                                                      useProxy,
                                                      proxyServer, proxyPort,
                                                      verbose );
            }
        }
    }

    if ( *useProxy == TRUE )
        if ( verbose )
            fprintf( stderr, "\tproxy = %s:%d\n",
                     proxyServer, *proxyPort );

    return ( isOperaActive );
}
Operaの設定ファイルからproxy関連情報を取得する処理

 Operaの設定ファイル(「OperaDef6.ini」または「opera6.ini」形式のファイル)からproxy関連情報を取得する処理の例を、以下に示します。

Operaの設定ファイルからproxy関連情報を取得する
/*
 *  Opera の設定情報から、proxy関連情報を取得する
 *      -- OperaDef6.ini 形式のファイルからproxy関連情報を取得する
 */
BOOL
readProxySettingFromOperaIni(
        const char     *filename,   /* (I) 解析対象 .ini ファイル名 */
        BOOL           *useProxy,   /* (O) proxy を使っているか否か */
        char           *proxyServer,/* (O) proxy サーバ名           */
        unsigned short *proxyPort,  /* (O) proxy ポート番号         */
        BOOL           verbose      /* (I) verbose モード           */
    )
{
    BOOL    found = FALSE;
    char    buf[BUFSIZ];
    char    *p;
    FILE    *fp;

    if ( ( fp = fopen( filename, "r" ) ) != NULL ) {
        while ( ( p = fgets( buf, BUFSIZ - 1, fp ) ) != NULL ) {
            if ( !strncmpi( p, "HTTP Server=",  12 ) ||
                 !strncmpi( p, "HTTPS Server=", 13 )    ) {
                    /* Opera 8 までは Server,                     */
                    /* Opera 9 は     server [s が小文字になった] */
                char    *q;

                found = TRUE;
                p = strchr( p + 11, '=' ) + 1;
                q = strchr( p, ':' );
                if ( !q ) {
                    q = p + (strlen(p) - 1);
                    while ( (q > p) && (*q == '\n') || (*q == '\r') )
                        *q-- = '\0';
                    strcpy( proxyServer, p );
                    *proxyPort = DEFAULT_HTTP_PORT;
                                        /* とりあえず、デフォルト値を */
                                        /* 入れておく                 */
                }
                else {
                    *q++ = '\0';
                    strcpy( proxyServer, p );
                    *proxyPort = (unsigned short)(atol( q ) & 0xFFFF);
                }
                *useProxy = TRUE;

                break;
            }
        }
        fclose( fp );
    }
    else {
        if ( verbose )
            fprintf( stderr, "設定ファイル(%s)が見つかりません\n", filename );
    }

    return ( found );
}

「通常使うブラウザ」の判定方法

 「通常使うブラウザ」(既定のWebブラウザ)がどのブラウザであるか判断し、その結果に基づいて、上記の各ブラウザごとのproxyサーバ情報読み出し処理を実行すれば、proxy情報を自動的に取得するプログラムを作成することができます。

 「通常使うブラウザ」が何であるかは、以下のレジストリの情報を元に判断します。

HKEY_CLASSES_ROOT\http\shell\open\ddeexec\Application

 上記のレジストリが存在しない場合は、htmlファイルをopenするのに使用するコマンドとして指定されているものを「通常使うブラウザ」とみなしても構わないと思います。

 以下のレジストリが「htmlファイルをopenするのに使用するコマンド」に相当します。

HKEY_CLASSES_ROOT\htmlfile\shell\open\command

 上記のレジストリに

  • iexplore(またはIExplore)を含む文字列が設定されていたら、「通常使うブラウザ」はInternet Explorer
  • firefox(またはFirefox)を含む文字列が設定されていたら、「通常使うブラウザ」はFirefox
  • opera(またはOpera)を含む文字列が設定されていたら、「通常使うブラウザ」はOpera

 ということになります。

「通常使うブラウザ」を判定する処理の例

「通常使うブラウザ」の設定を調べる
#define BR_UNKNOWN      0   /* 不明    */
#define BR_IEXPLORER    1   /* IE      */
#define BR_FIREFOX      2   /* Firefox */
#define BR_OPERA        3   /* Opera   */
#define BR_EXTRA        4   /* その他  */

int
getDefaultBrowser( void )
{
    int     ret = BR_UNKNOWN;
    long    r;
    HKEY    hk;
    long    type;
    char    buf[BUFSIZ];
    long    sz = BUFSIZ - 1;

    r = RegOpenKeyEx( HKEY_CLASSES_ROOT,
                      "http\\shell\\open\\ddeexec\\Application",
                      0,
                      KEY_READ,
                      &hk );
    if ( r != ERROR_SUCCESS )
        r = RegOpenKeyEx( HKEY_CLASSES_ROOT,
                          "htmlfile\\shell\\open\\command",
                          0,
                          KEY_READ,
                          &hk );
    if ( r == ERROR_SUCCESS ) {
        r = RegQueryValueEx( hk,
                             "",
                             NULL,
                             (unsigned long *)&type,
                             (unsigned char *)buf,
                             (unsigned long *)&sz );
        if ( r == ERROR_SUCCESS ) {
            if ( type == REG_SZ ) {
                if ( strstr( buf, "iexplore" ) ||
                     strstr( buf, "IExplore" )    )
                    ret = BR_IEXPLORER;
                else if ( strstr( buf, "firefox" ) ||
                          strstr( buf, "Firefox" )    )
                    ret = BR_FIREFOX;
                else if ( strstr( buf, "opera" ) ||
                          strstr( buf, "Opera" )    )
                    ret = BR_OPERA;
                else
                    ret = BR_EXTRA;
            }
        }
        RegCloseKey( hk );
    }

    return ( ret );
}

まとめ

 今回紹介した方法でproxyサーバ関連情報を取得するライブラリを用意しておけば、後々、Webを利用するプログラムを書くときに重宝すると思います。

 参考のため、実際にproxy情報を取得して、その結果を表示するサンプルプログラムを用意しました。Cで書いていますが、他のプログラミング言語への移植も難しくないと思います。

 また、いったんproxy関連の情報が格納されている場所(レジストリやファイル)が分かれば、それを書き換えるプログラムも作ることができます。ぜひ、今回の記事を参考にproxy情報設定ツールを作ってみてください。

 なお、サンプルプログラム(Shift_JIS, DOS形式)は、Visual C++ 6とVisual C++ 2005で各々コンパイルできることを確認しています。

参考資料

 Firefoxの設定ファイル「profiles.ini」に関しては

 に、Operaの設定ファイル「opera6.ini」に関しては

 に詳細な解説があり、これらを参考にしました。

 今回、この記事を書くにあたって、これらの解説に加えて、私が独自に調査した結果を利用しています。

この記事は参考になりましたか?

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
特集記事連載記事一覧

もっと読む

この記事の著者

tsu(ツ)

行き当たりばったり指向プログラミング」や「イベント参加報告」といったWebページを細々と書いています。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/813 2008/08/26 13:56

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー