概要

コマンドプロンプトで動作し、COMポートの一覧を表示します。
コンパイルにはWDK7が必要です。

実行例(2013/1/27追加)

COM1(通信ポート)
COM11(Prolific USB-to-Serial Comm Port)

2個のCOMポートが発見されました。

コンパイル方法

私は、Visual C++ 2008 Express Edition又はStandard Editonで動作確認をしている。動作OSは32bitの場合Windows XP~7、64bitの場合、Windows Vista~Windows 7(64bitアプリケーションとして実行可能)としている。Windows 8については多分動くと思われる。
コンパイルするには、WDK 7(http://msdn.microsoft.com/library/windows/hardware/gg487428)のインストールが必要である。
ユーザープログラムではusbio2.hをインクルードしusbio2.cppをユーザープログラムのプロジェクトに加え、WDK 7のインクルートディレクトリ・ライブラリディレクトリをVisual C++のプロジェクトに指定しなければならない。なお、インクルードファイルは、単純にWDK 7のインクルードパスのみ指定するとWDK 7のヘッダファイルがVisual C++標準のヘッダファイルより古いため同一ファイル名のヘッダファイルがある場合WDK 7の方が参照され意味不明のエラーが大量に発生する。例えば下記の様に指定するとVisual C++のヘッダファイルが優先されコンパイル可能となる。
$(VCInstallDir)include;C:\WinDDK\7600.16385.1\inc\api

ソースコード・実行ファイル

Visual C++ 2008用 ソース・実行ファイルのダウンロード


// COMポートの一覧を表示する(コマンドプロンプト用)
// Visual C++ 2008 UNICODE/マルチバイト  32bit/64bit
//
// 2013/09/08
//
//        コンパイルするにはWDK7がインストールされインクルードファイル及び
//  ライブラリファイルのパスが設定されている必要性があり
//        インクルードファイルのパス設定は、WDK7のみ設定するとインクルード
//   ファイルの呼び込み優先順位がWDK7→Visual C++標準パスとなりWDK7の
//   ヘッダーファイルから古いヘッダファイルがインクルードされエラーが
//   多数発生するため、優先順位をVisual C++標準パス→WDK7となるようにする
//   インクルードパスの設定例
//     追加のインクルードディレクトリ $(VCInstallDir)include;C:\WinDDK\7600.16385.1\inc\api
//              ライブラリディレクトリの設定も必要
//              Win32 C:\WinDDK\7600.16385.1\lib\wxp\i386
//              Win64 C:\WinDDK\7600.16385.1\lib\wlh\amd64
//

#include <windows.h>
#include <stdio.h>
#include <setupapi.h>
#include <locale.h>
#include <tchar.h>

extern "C" {
        #include "hidsdi.h"
}

#pragma comment(lib,"hid.lib")
#pragma comment(lib,"setupapi.lib")

int comList(void){
        HDEVINFO hDevInfo;
        DWORD MemberIndex=0;
        SP_DEVINFO_DATA Data={ sizeof(SP_DEVINFO_DATA) };

        int max=0;
        hDevInfo=SetupDiGetClassDevs(&GUID_DEVINTERFACE_COMPORT,0,0,DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); // デバイス情報セットを取得
        if(hDevInfo==0) //      デバイス情報セットが取得できなかった場合
                return 0;
        Data.cbSize=sizeof(Data);

        while( SetupDiEnumDeviceInfo(hDevInfo,max,&Data)){  // デバイスインターフェイスの取得
                DWORD dataT;
                DWORD size;
                LPTSTR buf;
//      COMポート名の取得
                HKEY key=SetupDiOpenDevRegKey(hDevInfo,&Data,DICS_FLAG_GLOBAL,0,DIREG_DEV,KEY_QUERY_VALUE);
                if(key){
                        TCHAR name[256];
                        DWORD type=0;
                        size=sizeof(name);
                        RegQueryValueEx(key,_T("PortName"),NULL,&type,(LPBYTE)name,&size);
                        _tprintf(_TEXT("%s"),name);
                }
//      デバイスの説明を取得
                size=0;
                buf=NULL;
                while(!SetupDiGetDeviceRegistryProperty(hDevInfo,&Data,SPDRP_DEVICEDESC,&dataT,(PBYTE)buf,size,&size)){
                        if(GetLastError()==ERROR_INSUFFICIENT_BUFFER){
                                if(buf)
                                        LocalFree(buf);
                                buf=(LPTSTR)LocalAlloc(LPTR,size*2);
                        }else
                                break;
                }
                _tprintf(_TEXT("(%s)\n"),buf);
                if(buf)
                        LocalFree(buf);


                ++max;
        }
        SetupDiDestroyDeviceInfoList(hDevInfo); //      デバイス情報セットを解放
        return max;
}

int _tmain(void){
        _tsetlocale(LC_ALL,_TEXT(""));
        int max=comList();
        _tprintf(_TEXT("\n%i個のCOMポートが発見されました。\n"),max);

}