CsWin32 を別プロジェクトに分離する
はじめに
C# から Windows API を呼びだす際、今までは P/Invoke を手動で書いたり、PInvoke.User32 等のパッケージを使ったりしていました。
最近 CsWin32 が登場し、より汎用的に使えるようになりましたが、欠点としては、アンセーフコード(unsafe)の使用が挙げられます。
解決策としては、CsWin32 をメインプロジェクトにインストールするのではなく、独立したプロジェクトとして分離すれば良いのですが、そのやり方がまとまっているところが意外と見当たらなかったので、ここに整理してまとめておきます。
サンプルプログラムのソースコードは GitHub に上げてあります。
サンプルプログラムは Visual Studio 2022 で作成し、.NET 7 で Windows App SDK (WinUI 3) を使用していますが、他のフレームワークでもほぼ同様のやり方でいけるのではないかと思います。
空プロジェクトの作成
ソリューションの中で、メインプロジェクトとは別のプロジェクトを新規に作成します。
デフォルトの中身は不要なので、なるべく空に近いテンプレートでプロジェクトを作成します。今回は「クラスライブラリ」にしました。
今回はメインプロジェクトが「TestCsWin32」なので、空プロジェクトの名称は「TestCsWin32.CsWin32」にしました。デフォルトで作成されるプロジェクトの中身(Class1.cs)は削除します。
ソリューションの構成は以下のようになります。
ソリューション TestCsWin32
├── TestCsWin32(メインプロジェクト)
├── TestCsWin32.CsWin32(CsWin32 プロジェクト用の空プロジェクト)
└── その他のプロジェクト
CsWin32 導入
新規作成した空プロジェクトを、CsWin32 プロジェクトにしていきます。
[ツール → NuGet パッケージマネージャー → ソリューションの NuGet パッケージの管理]メニューから CsWin32 パッケージをインストールします。
インストール先はメインプロジェクトではなく、空プロジェクト(TestCsWin32.CsWin32)です。
CsWin32 をインストールした時点で、TestCsWin32.CsWin32 プロジェクトのアンセーフコードが有効になります。一方で、メインプロジェクトはアンセーフコードは無効のままにできます。
TestCsWin32.CsWin32 プロジェクトの直下に「NativeMethods.txt」を作成し、使用したい Windows API を列挙します。今回は関数を列挙していますが、「User32.*」のようにモジュール一括指定も可能です。
CloseWindow
GetForegroundWindow
メインプロジェクトから参照できるようにするため、TestCsWin32.CsWin32 プロジェクトの直下に「NativeMethods.json」を作成し、public 設定をします。
{
"$schema": "https://aka.ms/CsWin32.schema.json",
"public": true
}
ここまでしたら、TestCsWin32.CsWin32 プロジェクトをビルドしておきます。
Windows API 使用
メインプロジェクトで Windowws API を使用するには、メインプロジェクトの「依存関係」からプロジェクト参照の追加をします。
参照マネージャーで TestCsWin32.CsWin32 プロジェクトを追加します。
Windows.Win32 名前空間で、「NativeMethods.txt」で指定した Windows API が呼べるようになります。
using Windows.Win32;
using Windows.Win32.Foundation;
HWND hwnd = PInvoke.GetForegroundWindow();
インテリセンスでのサジェストもされます。もしサジェストされない場合は、ソリューションをリビルドしたり、Visual Studio を再起動したりするといいかもしれません。
名前空間
構造体などは名前空間の深い位置に配置される場合があり、探しづらいことがあります。
ソリューションエクスプローラーで TestCsWin32.CsWin32 プロジェクトの依存関係(アナライザー)を見ると、Microsoft.Windows.CsWin32
配下に生成されたソースコードがリストされています。ダブルクリックで開くと内容を確認できるので、名前空間も分かります。
サンプルプログラム
サンプルプログラム(GitHub に上げてあります)を実行すると、ウィンドウハンドルを取得します。
確認環境
項目 | 環境 |
---|---|
OS | Windows 11 Pro 22H2 |
Visual Studio | 2022 17.7.1 |
.NET | 7.0 |
Windows App SDK | 1.4 Preview 2 (1.4.230811000) |
CsWin32 | 0.3.18-beta |
主な改訂履歴
- 2023/08/19 初版。
- 2024/11/14 名前空間を記載。
Discussion