7
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

#62 【C#】Win32APIのDllImportを簡略化した

Posted at

C#でWin32APIを利用する際、一々DllImportを記述するのが非常に面倒だったので、手軽に利用できる方法を調べました。

没案1: PInvoke.net Visual Studio Extensionを使用する

PInvoke.net Visual Studio Extension は、DllImportの入力を補助してくれるVisualStudioの拡張機能のようです。残念ながら、私が使用している Visual Studio 2022 はサポートしていないらしく、Visual Studio上のマーケットプレイスでヒットせず、直接ダウンロードしてのインストールも失敗しました。
試していませんが、こちらを参考にサポートバージョンを無理やり書き換えればインストールできるかもしれません。

没案2: PInvoke.netからコピペする

PInvoke.netは、Win32APIのDllImport文がまとまっているサイトのようです。こちらのページで該当のWin32APIを検索し、import文をコピペするよう促している記事がいくつかありました。
ただし、筆者が確認した2024年3月時点では404エラーが出てしまいページ自体開けませんでした。

結論: CsWin32を使う

Microsft が提供する CsWin32 というパッケージを使用して、呼び出したい Win32APIをプロジェクト内に生成することができました。

手順1

VisualStudio の ツール > Nugetパッケージマネージャー > ソリューションのNugetパッケージの管理 から CsWin32 をインストールする

※プレリリースを含める にチェックを入れないと見つかりません

image.png

手順2

NativeMethods.txt という名前のテキストファイルを作成し、使用したいAPI名を記述する

NativeMethods.txt
WH_KEYBOARD_LL
SetWindowsHookEx
GetModuleHandle

手順3

ソリューションをビルドする
image.png

========== ビルド: 成功 1、失敗 0、最新の状態 0、スキップ 0 ==========

ビルド成功したら、完了です。
あとは、主に PInvoke.*** の形で使用したいAPIを呼び出せるはずです。
APIの呼び出し箇所から、定義へのジャンプもできるようになります。

修正前後比較

参考までに、修正前後のコードの一部を記載します。
NativeMethods.txt への追記が必要とはいえ、非常に手間が省けたのが分かるかと思います。

修正前
protected const int WH_KEYBOARD_LL = 0x000D;

[DllImport("user32.dll",  CharSet  =  CharSet.Auto,  SetLastError  =  true)]
private  static  extern IntPtr SetWindowsHookEx(int  idHook,  KeyboardProc lpfn,  IntPtr hMod,  uint dwThreadId);

[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);

SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curModule.ModuleName), 0);
PInvoke.SetWindowsHookEx(WINDOWS_HOOK_ID.WH_KEYBOARD_LL, proc, PInvoke.GetModuleHandle(curModule.ModuleName), 0);

注意点

  • 自動生成されたコードの要求バージョンに応じて、C#のバージョンアップが必要になる可能性があります。

    • C#バージョン不足によるビルドエラーが表示された場合、.csprojファイルの<PropertyGroup>内 に、C#バージョンを追記
      <LangVersion>9.0</LangVersio
      
  • 元々Dllimportを使用していた箇所は型の見直しが必要になる可能性があります。

    • IntPtr型にしてたところをenumにする等。

以上です。
最後まで読んでいただきありがとうございます。

参考

7
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?