実現したいこと
- Screen Captureのサンプル(.NET 4.7.2/.NET Standard 2.0)を.NET 6に移行させたい
- フレームワークを変更した際に起きるInvalidCastExceptionを解決したい
前提
C#/.NET 6で画面キャプチャを行うアプリケーションを作っています。
機能の実現のため、UWPの機能であるWindows.Graphics.Captureを利用したいのですが、
アプリ自体は他の機能の兼ね合いもありWPFで作成しています。
下記URLにMicrosoftのサンプルがあり、これを流用したいと考えました。
https://github.com/microsoft/Windows.UI.Composition-Win32-Samples/tree/master/dotnet/WPF/ScreenCapture
このサンプルは.NET Framework 4.7.2が利用されており、サポート切れであるため.NET 6を利用したく、上記サンプルのプロジェクトを.NET 6から参照し、機能を呼び出すこととしました。
サンプルに含まれていたプロジェクトであるComposition.WindowsRuntimeHelpersとCaptureSampleCoreは.NET Standard 2.0が利用されており、これは.NET 6のプロジェクトから参照できないため、TargetFrameworkを.NET 6(net6.0-windows10.0.22000.0)に変更し、NuGetパッケージのMicrosoft.Windows.SDK.Contractを削除しました。WinRTを利用するためにOSバージョンの記載を付加しています。
ここで、ビルドは正常に行えるのですが、キャプチャを実行しようとした際、Direct3D11CaptureFramePool.CreateにてInvalidCastExceptionが発生しました。
発生している問題・エラーメッセージ
コンパイラはエラーを出さず、実行時に下記の例外が発生します。
System.InvalidCastException: 'Specified cast is not valid.'
該当のソースコード
テストとして、MainWindows.xaml.csより、ボタンがクリックされた際に以下のコードでキャプチャを開始するようにしました。
C#
1 var picker = new GraphicsCapturePicker(); 2 CaptureHelper.SetWindow(picker, hwnd); 3 GraphicsCaptureItem item = await picker.PickSingleItemAsync(); 4 5 if (item != null) 6 { 7 capture = new BasicCapture(device, item); 8 9 capture.StartCapture(); 10 }
CaptureHelper.SetWindowでもInvalidCastExceptionが出たため、サンプルから下記のように変更することで対処できました。
C#
1 public static void SetWindow(this GraphicsCapturePicker picker, IntPtr hwnd) 2 { 3 //キャストせずに直接Initializeを呼び出しに変更 4 //var interop = (IInitializeWithWindow)(object)picker; 5 //interop.Initialize(hwnd); 6 WinRT.Interop.InitializeWithWindow.Initialize(picker, hwnd); 7 }
capture = new BasicCapture(device, item);ではコンストラクタが呼ばれ、その中の下記部分で該当の例外が起きています。
C#
1 framePool = Direct3D11CaptureFramePool.Create( 2 device, 3 DirectXPixelFormat.B8G8R8A8UIntNormalized, 4 2, 5 i.Size); 6
試したこと
同様のコードで.NET Framework 4.7.2のプロジェクトから呼び出すことは問題ないことを確認しました。
.NETのバージョン違いによるキャストの仕様について調べてみましたが、答えにたどり着けていません。
ご存じの方がいらっしゃいましたらご教示いただければと思います。
補足情報(FW/ツールのバージョンなど)
Visual Studio 2022 Version 17.5.4
回答2件
あなたの回答
tips
プレビュー