VS2022 Communityが入った状態からstart
devconのサンプルをMSのrepositoryからダウンロード
https://github.com/microsoft/Windows-driver-samples/tree/main/setup/devcon
VS2022で開いてビルドしようとすると、msg.h
がないと怒られる。
なんで?なにかが足りてない?とりあえず思いつくものをinsutallしてみる。
WDKをインストール
https://learn.microsoft.com/ja-jp/windows-hardware/drivers/download-the-wdk
こんなんが出てきた
VS2022にC++デスクトップのワークロードがたりない、インストールせよ、と言っているが、VSinstaller見た限りでは、C++デスクトップはインストール済みのように見える。
→よくわからんので、そのまま進む。
こうなった。チェックは入れとく。
vsixでインストールが始まった
入れ終わった。
が、これでもVS2022でdevconビルドしようとすると、msg.hが無いと怒られた。
下記ページに、VS2019だとうまくビルドできるとある。やってみる。
https://github.com/microsoft/Windows-driver-samples/pull/991
vs2019だと、別のエラーになった。
下記のページに、「WDK.vsix」をインストールするとうまくいくとある。
https://qiita.com/skitoy4321/items/4e1cc3ab939aabf23fd6
これかな?インストールしてみる。
C:\Program Files (x86)\Windows Kits\10\Vsix\VS2022\10.0.22621.0\WDK.vsix
→すでに入ってると言われた。↑で入れたやつがこれなのか。
これをやってみる。
ここのx64フォルダを、
C:\Users\masa\Desktop\WDK\$MSBuild\Microsoft\VC\v170\Platforms\x64
ここに上書コピーする。
C:\Program Files\Microsoft Visual Studio\2022\Community\Msbuild\Microsoft\VC\v170\Platforms
だめだった。
これらをDL&インストールしてみた。
WDK for Windows 10 バージョン 2004 をインストールしたら、VS2019で出てたtoolsetがないというエラーは出なくなった。が、VS2022とおなじ、msg.hがないエラーは同じ。
これを入れてみる。Windows 11 SDK (10.0.22621.0
https://developer.microsoft.com/en-us/windows/downloads/windows-sdk/
要らないものをいれるのはいやだけど、どれがいらないかわからないので全チェック入れてインストールしてみる。
この図の、下の4つの「Windows SDK for Desktop C++ なんとか・・」が、上のINportant何とか画面ででてた、足りないヤツなのか?
下記に、本家のDevConからforkしたリポジトリに、msg.hがあった。
https://github.com/WOA-Project/DevCon/tree/main
これをもらってきてみる。
→もらってきて、文字コードSJISで保存しなおしてビルドしたら、エラーが変わった。
ここをみて、Spectre軽減設定をOFFにしてみる
https://learn.microsoft.com/ja-jp/visualstudio/msbuild/errors/msb8040?view=vs-2022
→ビルドできた!
出力先フォルダに移動して、VSの開発者用powershellで、./devcon.exe help
と打つと、devconのhelpを見れた。
./devcon.exe find *
と打つと、ドライバの一覧っぽいのが見れた。どうやらうまく動いたっポイ。
ここまでやってみた感想
おそらく、途中でやってたWDKやそのオマケのVS用アドオンvsix、windowsSDKのインストールはいらなかったっぽい。最後にやった、forkのリポジトリからmsg.hを持ってきたのだけが、効果があった気がする。(検証はしてない)
本家のmsg.hがどこへ消えたのか?は分からずじまい。
だがともかく、DevConを動かせたので、とりあえず掲題の勉強はできそう。
ビルドしたDevConを動かしてみた。
試しに下記コマンドを打つと、
devcon classes
日本語が化ける。
ターミナルでchcp 65001
とかしてもダメだった。
色々試した結果、devconのコード中で、setlocale(LC_ALL, "Japanese");
をしてやれば化けなくなった。
参考:
https://oshiete.goo.ne.jp/qa/5388646.html
devcon.cppの冒頭に下記を書いて、
#include <locale.h>
devcon.cpp の _tmain() の開始直後に下記を入れた。
setlocale(LC_ALL, "Japanese");
これで、うまく日本語が出てくれた。
devcon、動かすとなんだかいろんな情報が取れてるっぽいが、それが何を示しているのかさっぱりわからない。
下記ページがなんかよさそう?見てみる。
https://sciencepark.co.jp/device_driver/dvdr_report/
ちょっと横道にそれるが、chatgptに、
Windowsのデバイスマネージャー画面に出てくる一覧は、なんの一覧でしょうか?メニューの「表示」は、「デバイス(種類別)」にチェックが入っています。
さらに
この一覧と同じ内容を、windowsのAPIで取得したい場合、どのようなAPIを使えばよいでしょうか?
と聞いて出てきたC++コードをちょっと直してやると、デバマネの最初に出てくる一覧と似た内容が取れた。たぶんdevconにも、似た内容があるんだろうと思う。とりあえずメモ。
#include <windows.h> #include <Setupapi.h> #include <devguid.h> #include <stdio.h> #pragma comment(lib, "Setupapi.lib") // 文字コードを、マルチバイト文字列、にすべし void PrintDeviceProperty(HDEVINFO deviceInfoSet, PSP_DEVINFO_DATA deviceInfoData, DWORD property) { DWORD requiredSize = 0; SetupDiGetDeviceRegistryProperty(deviceInfoSet, deviceInfoData, property, NULL, NULL, 0, &requiredSize); if (requiredSize == 0) { printf("Property not found.\n"); return; } BYTE* buffer = (BYTE*)malloc(requiredSize); if (buffer == NULL) { printf("Memory allocation failed.\n"); return; } if (!SetupDiGetDeviceRegistryProperty(deviceInfoSet, deviceInfoData, property, NULL, buffer, requiredSize, NULL)) { printf("Failed to retrieve property.\n"); free(buffer); return; } printf("%s\n", (char*)buffer); free(buffer); } int main() { HDEVINFO deviceInfoSet = SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_PRESENT | DIGCF_ALLCLASSES); if (deviceInfoSet == INVALID_HANDLE_VALUE) { printf("Failed to get device information set.\n"); return 1; } SP_DEVINFO_DATA deviceInfoData; ZeroMemory(&deviceInfoData, sizeof(deviceInfoData)); deviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); for (DWORD i = 0; SetupDiEnumDeviceInfo(deviceInfoSet, i, &deviceInfoData); i++) { printf("Device %lu:\n", i + 1); PrintDeviceProperty(deviceInfoSet, &deviceInfoData, SPDRP_DEVICEDESC); // デバイスの説明 PrintDeviceProperty(deviceInfoSet, &deviceInfoData, SPDRP_HARDWAREID); // ハードウェアID printf("\n"); } SetupDiDestroyDeviceInfoList(deviceInfoSet); }
出力結果の一部
Device 1: WinDriver *WINDRVR6 Device 2: ローカル印刷キュー PRINTENUM\{0f4130dd-19c7-7ab6-99a1-980f03b2ee4e} Device 3: Intel(R) Dynamic Application Loader Host Interface SWC\3C4852D6-D47B-4F46-B05E-B5EDC1AA440E Device 4: Microsoft Bluetooth LE Enumerator BTH\MS_BTHLE Device 5: マザーボード リソース ACPI\VEN_PNP&DEV_0C02 Device 6: マザーボード リソース ACPI\VEN_PNP&DEV_0C02
DevConで、情報を取る部分で、どうかかれているかを見てみる。