kkamegawa's weblog

Visual Studio,TFS,ALM,VSTS,DevOps関係のことについていろいろと書いていきます。Google Analyticsで解析を行っています

取得する方法は一つではない

今日お仕事のプログラム作っていて、プリンタとそのプリンタドライバを列挙させる処理が必要になりました。プリンタ一覧はSystem.Drawing.PrinterSettingsのInstalledPrintersプロパティで取得できます。しかし、ドライバ名までは取得できません*1。ネイティブコードで作るか〜と思っていたら、WMIで取得できたんですね。
Windows APIでは

  • EnumPrinters()でまず「いくつプリンタがあるか」取得して、メモリ確保
  • EnumPrinters()でプリンタ列挙(実際に取得するならPRINTER_INFO_2あたりがいいけれど、存在確認だけならPRINTER_INFO_4がおすすめ)
  • あとは必要に応じてOpenPrinter(),GetPrinter(),ClosePrinter()

…と言葉で書くと簡単だけど、結構書く必要があります(エラー処理ちゃんとやると30行くらいかなぁ)。実際やりたくない(笑)。が、WMI+C#だと

using System.Management;

System.Management.ObjectQuery oq = new System.Management.ObjectQuery("SELECT * FROM Win32_Printer");
ManagementObjectSearcher query1 = new ManagementObjectSearcher(oq);
ManagementObjectCollection queryCollection1 = query1.Get();
foreach(ManagementObject mo in queryCollection1) {
    Console.WriteLine("Printer Driver : " + mo["DriverName"].ToString());  //ドライバ名
    Console.WriteLine("Printer Driver : " + mo["Name"].ToString());        //プリンタ
}

これだけ。なんて楽!WMIはクエリを構築するときの参照元みつけるのがやや手間(ツールもある)だけど、ネイティブコード書くことを思えばむちゃくちゃ便利ですね。デバイス列挙は全部とれるのかな。Enum系のAPI使う機会はぐっと減りそうです。

という順番だったけど

という流れにするべく意識を植え付けよう。

*1:私はまだ.NET 1.1を使っています