CsWin32 を別プロジェクトに分離する

2023/08/19に公開

はじめに

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 パッケージをインストールします。

2023 年 8 月時点では CsWin32 パッケージはプレリリースなので、「プレリリースを含める」にチェックを入れないと検索に出てきません。インストール先はメインプロジェクトではなく、空プロジェクト(TestCsWin32.CsWin32)です。

CsWin32 をインストールした時点で、TestCsWin32.CsWin32 プロジェクトのアンセーフコードが有効になります。一方で、メインプロジェクトはアンセーフコードは無効のままにできます。

TestCsWin32.CsWin32 プロジェクトの直下に「NativeMethods.txt」を作成し、使用したい Windows API を列挙します。今回は関数を列挙していますが、「User32.*」のようにモジュール一括指定も可能です。

NativeMethods.txt
CloseWindow
GetForegroundWindow

メインプロジェクトから参照できるようにするため、TestCsWin32.CsWin32 プロジェクトの直下に「NativeMethods.json」を作成し、public 設定をします。

NativeMethods.json
{
	"$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 を再起動したりするといいかもしれません。

サンプルプログラム

サンプルプログラム(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

Discussion