スタートメニューからVisual C++のコマンドプロンプトを抽出し指定したコマンドを実行する

icon 項目のみ表示/展開表示の切り替え

概要

OpenSSLのライブラリを作成するときなど、Visual C++のコマンドプロンプト上でコンパイルする必要があります。
32bit版・64bit版や複数バージョンのVisual C++を使用したい場合、そのつどVisual C++コマンドプロンプトを起動してコンパイルする必要があり時間のかかるコンパイルの場合、煩雑です。
本プログラムは、スタートメニューからインストールされているVisual C++コマンドプロンプトを一括取得し、チェックをしているコマンドプロンプト上で指定したコマンドを実行することができます。
コマンドはバッチファイル等を想定しており、バッチファイルへの引数としてコンパイル環境(32bit・64bit,コンパイラのバージョン,release・debug)を引き渡すことができます。
下図のスクリーンショットは、Visual C++ 2008のコマンドプロンプト上でバッチファイルmakesslを実行する例です。
実行するコマンドのエディットボックスでコマンド名を指定しており、makesslがコマンド名、第1引数は%PLAT%なのでx86,、第2引数は%IVER%なのでコンパイラの内部バージョン、第3引数はreleaseとdebugが暗黙のうちに適用されます。
%変数名%は以下の変数名が使用可能です。

%PLAT%          環境 x86 or x64に置き換わる
%VER%           Visual C++ 製品バージョン 2005/2008/2010/2013
%IVER%          Visual C++ 内部バージョン 8 9 10 11 12
%_MSC_VER%      Visual C++ マクロ _MSC_VERと同じ値
この状態で実行をクリックするとVisual C++ 2008のコマンドプロンプトを実行後に以下のように指定したコマンドが実行されます。

makessl x86 9 release
makessl x86 9 debug
実行内容は実行内容エディットボックスのテキストのとおりです。
作業フォルダーが空白の場合、コマンドはカレントフォルダーまたは、環境変数Pathで検索できるフォルダーの必要があります。
作業フォルダーに有効なフォルダー名が入力されている場合、Visual C++ 2008コマンドプロンプト実行後、pushdコマンドでカレントフォルダーを作業フォルダーに移動します。

Visual C++コマンドプロンプトに複数のチェックを入れれば一括してコマンドを実行することができます。

テスト環境

コンパイラ

Visual C++ 2008/2010/2013 Express 32/64bit マルチバイト/UNICODE

実行環境

Visual C++ 2005のマルチバイトでコンパイルした場合、Windows98SEで実行できます。
Visual C++ 2008でコンパイルした場合、Windows 2000以上で実行できます。

プログラムソースの概要

Visual C++をインストールした場合のスタートメニューの構成について

CドライブにVisual C++をインストールするとスタートメニュー等は以下のようなフォルダー構成になります。

Windows 2000 + Visual C++ 2005 Expressの場合


C:\DOCUMENTS AND SETTINGS\ALL USERS\スタート メニュー\プログラム\VISUAL C++ 2005 EXPRESS EDITION
│  Microsoft Visual C++ 2005 Express Edition.lnk
│  
└─Visual Studio Tools
        Visual Studio 2005 コマンド プロンプト.lnk
                        ↓
          %comspec% /k ""C:\Program Files\Microsoft Visual Studio 8\VC\vcvarsall.bat"" x86

ComSpec=C:\WINNT\system32\cmd.exe

Windows XP + Visual C++ 2008 Expressの場合


C:\DOCUMENTS AND SETTINGS\ALL USERS\スタート メニュー\プログラム\MICROSOFT VISUAL C++ 2008 EXPRESS EDITION
│  Microsoft Visual C++ 2008 Express Edition.lnk
│  
└─Visual Studio Tools
        Visual Studio 2008 コマンド プロンプト.lnk
                        ↓
          %comspec% /k ""C:\Program Files\Microsoft Visual Studio 9.0\VC\vcvarsall.bat"" x86

ComSpec=C:\WINDOWS\system32\cmd.exe

Windows VISTA + Visual C++ 2010 Express


C:\PROGRAMDATA\MICROSOFT\WINDOWS\START MENU\PROGRAMS\MICROSOFT VISUAL STUDIO 2010 EXPRESS
    Microsoft Visual C++ 2010 Express.lnk
    Visual Studio 2010 Professional を試す.url
    Visual Studio コマンド プロンプト (2010).lnk
                        ↓
      %comspec% /k ""C:\Program Files\Microsoft Visual Studio 10.0\VC\vcvarsall.bat"" x86

ComSpec=C:\WINDOWS\system32\cmd.exe

Windows 7 + Visual C++ 2008の場合


C:\PROGRAMDATA\MICROSOFT\WINDOWS\START MENU\PROGRAMS\MICROSOFT VISUAL STUDIO 2008
│  Microsoft Visual Studio 2008 ドキュメント.lnk
│  Microsoft Visual Studio 2008.lnk
│  
└─Visual Studio Tools
        Dotfuscator Community Edition.lnk
        MFC-ATL トレース ツール.lnk
        Spy++ (64 ビット).lnk
        Spy++.lnk
        Visual Studio 2008 x64 Cross Tools コマンド プロンプト.lnk
        Visual Studio 2008 x64 Win64 コマンド プロンプト.lnk
                        ↓
          %comspec% /k ""C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\vcvarsall.bat"" amd64

        Visual Studio 2008 コマンド プロンプト.lnk
                        ↓
          %comspec% /k ""C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\vcvarsall.bat"" x86
        Visual Studio 2008 リモート デバッガ (x64).lnk

Windows 7 + Visual C++ 2013 Expressの場合


C:\PROGRAMDATA\MICROSOFT\WINDOWS\START MENU\PROGRAMS\VISUAL STUDIO 2013
    VS Express 2013 for Desktop.lnk
    別の Visual Studio 2013 製品を試す.url
    Visual Studio ツール.lnk
                        ↓
      C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\Tools\Shortcuts
        VS2013 x64 Cross Tools コマンド プロンプト.lnk
                        ↓
          %comspec% /k ""C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat"" x86_amd64
        VS2013 x86 Native Tools コマンド プロンプト.lnk
                        ↓
          %comspec% /k ""C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat"" x86
        ビルド通知.lnk
        開発者コマンド プロンプト for VS2013.lnk
ComSpec=C:\Windows\system32\cmd.exe

get_vc_cmd.cpp

_tWinMain

chk_vc_cmd関数によりVisual C++コマンドプロンプトの一覧を取得します。
ダイアログボックスを表示します。

DlgProc

ダイアログボックスのプロシージャです。
WM_INITDIALOG
ダイアログボックスの初期化時に呼び出されます。
リストビューにVisual C++コマンドプロンプトの一覧を表示します。
WM_NOTIFY
ダイアログボックスの子ウィンドウであるコモンコントロールからのメッセージです。子ウィンドウが親ウィンドウにWM_NOTIFYメッセージを発生されるためには子ウィンドウのスタイルにSS_NOTIFYを追加する必要があります。
wParamをチェックしリストビューからのメッセージで右クリック(NM_CLICK)の場合、選択されている行を取得し、make_cmd_str関数により実行するバッチファイルの内容を作成し、その内容をエディットボックスに表示します。
WM_COMMAND
エディットボックスの変更、プッシュボタンのクリック時に呼び出されます。
IDC_REF_BUTTON
参照ボタンをクリックした場合に呼び出されます。
GetDir関数経由でフォルダー名を取得するコモンダイアログを呼び出します。
IDC_CMD_EDIT
実行するコマンドのエディットボックスのメッセージのうちエディットボックスが変更された場合(EN_UPDATE)に処理を行います。
ListView_GetNextItemマクロにより選択されているリストビューの行番号を取得します。
make_cmd_str関数により実行するバッチファイルの内容を作成し、その内容をエディットボックスに表示します。
IDC_DIR_EDIT
作業フォルダーのエディットボックスのメッセージのうちエディットボックスが変更された場合(EN_UPDATE)に処理を行います。
ListView_GetNextItemマクロにより選択されているリストビューの行番号を取得します。
make_cmd_str関数により実行するバッチファイルの内容を作成し、その内容をエディットボックスに表示します。
IDOK
実行ボタンをクリックした場合とReturnキーを押した場合に呼び出されます。
リストビューでチャックされているコマンドプロンプトを抽出し、Visual C++コマンドプロンプトと指定したコマンドを呼び出すバッチファイルを作成します。
構成のチェックボックスである、Release・Debugがチェックの状況を取得します。
チェックされている場合、それぞれ別々のバッチファイルを作成します。
プログレスバーを設定し、順番にバッチファイルを実行します。
メッセージボックスを表示し、EndDialogによりダイアログボックスを終了します。
IDCANCEL
キャンセルボタンをクリックした場合とESCキーを押した場合に呼び出されます。
EndDialogによりダイアログボックスを終了します。

chk_vc_cmd

スタートメニューよりVisual C++のコマンドプロンプトへのショートカットを取得する関数です。
ショートカットの取得には、IPersistFileインターフェースを使用します。
詳細は、COMを使用してショートカットのリンク先を取得する(32/64bit)を参照してください。
COMを初期化し、IShellLinkオブジェクト、IPersistFileオブジェクトを作成します。
SHGetSpecialFolderPath APIを用いてAllユーザーのスタートメニューのフォルダー名を取得します。
詳細は、スタートメニューのフォルダー名を取得するを参照してください。
取得されたスタートメニューのフォルダー名よりfind_vc関数によりVisual C++のコマンドプロンプトへのショートカットの一覧をvc_cmd配列に取得します。
IPersistFileオブジェクトからショートカットの先とオプションを示す文字列を取得します。 取得された内容の例を以下に示します。

C:\Windows\system32\cmd.exe /k ""C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat"" x86
取得された内容よりVisual C++のバージョンはget_vc_ver関数、ビット数はget_vc_bit関数により取得し配列に格納します。
最後にIPersistFileオブジェクト、IShellLinkオブジェクトを解放します。

find_vc

スタートメニューのフォルダー名よりフォルダーを検索しVisual C++コマンドプロンプトの一覧を作成し、vc_cmd配列に格納する関数です。
FindFirstFile API、FindNextFile APIによりフォルダーを検索し、Visual C++のフォルダー及びツールフォルダーを特定しその中のショートカットを取得します。
Visual C++のフォルダー及びツールフォルダーがショートカットの場合、link_target関数を呼び出しショートカットのリンク先のフォルダーを取得し、その中に含まれるショートカットを取得します。

vc_dir_chk

find_vc関数から呼び出され、Visual C++のフォルダー名の場合、trueを返します。

vc_tool_dir_chk

find_vc関数から呼び出され、Visual C++のフォルダーのツールを検出した場合trueを返します。

link_target

find_vc関数から呼び出され、ショートカットのリンク先を取得します。

get_vc_ver

find_vc関数から呼び出され、Visual C++の製品番号を取得します。

get_vc_bit

find_vc関数から呼び出され、ビット数を取得します。
32bitの場合64を64bitの場合64を返します。

make_cmd_str

Visual C++ コマンドプロンプトと指定されたコマンドを実行するバッチファイルを作成する関数です。
引数numはリストビューの行位置を示し、これに該当するvc_cmd配列の添え字番号を取得します。
arg_rep関数により、変数を展開します。
引数cmdで示される位置にバッチファイルの中身を保存します。 バッチファイルからバッチファイルを直接呼び出すと元のバッチファイルに戻ってこないのでCALLを使用して呼び出します。 作業フォルダー(def_dir配列)にフォルダー名が格納されている場合、pushdコマンドを追加します。

arg_rep

make_cmd_str関数から呼び出され、変数を実際の文字に置き換えます。
使用できる変数は以下のとおりです。
%PLAT%
Visual C++コマンドプロンプトの内容よりWIN32向けかWIN64向けを判断し、x86またはx64の文字列に置き換えます。
%VER%
Visual C++コマンドプロンプトの内容より製品バージョンを示す文字列に置き換えます。
Visual C++ 2013の場合、2013という文字列に置き換わります。
%IVER%
Visual C++コマンドプロンプトの内容より内部バージョンを示す文字列に置き換えます。
Visual C++ 2013の場合、12という文字列に置き換わります。
%_MSC_VER
Visual C++コマンドプロンプトの内容よりVisual Cのソースコードで使用できる_MSC_VERマクロと同じ値の文字列に置き換えます。
Visual C++ 2013の場合、1800という文字列に置き換わります。

cmd_opt2bat

make_cmd_str関数から呼び出されます。
ショットカットのオプション文字より、実際のバッチファイル名を取得します。
たとえば以下の文字列の場合、"C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat"が返されます。

/k ""C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat"" x86

GetDir

SHBrowseForFolderを用いフォルダー名を取得します。
詳細は、SHBrowseForFolderによりフォルダー名を取得するプログラム(32/64bit)を参照してください。

ソースファイルと実行ファイル