久し振りに UWP なアプリケーションの更新をしていたところ、リリースビルドの場合のみ共有時に例外となって、動かなくなっていたことに気が付いてしまいました。
回避法が分かったのでメモとして残しておきます。あと最小限の再現コードを参考までに載せておきます。
public sealed partial class MainPage : Page { public MainPage() { InitializeComponent(); } protected override void OnNavigatedTo(NavigationEventArgs e) { base.OnNavigatedTo(e); var dataTransferManager = DataTransferManager.GetForCurrentView(); dataTransferManager.DataRequested += DataTransferManager_DataRequested; } private async void DataTransferManager_DataRequested(DataTransferManager sender, DataRequestedEventArgs args) { var request = args.Request; var deferral = request.GetDeferral(); var storageItem = await KnownFolders.PicturesLibrary.GetFileAsync("kazuakix.jpg"); request.Data.Properties.Title = "kazuakix"; request.Data.SetStorageItems(new[] { storageItem }, true); deferral.Complete(); } private void Button_Click(object sender, RoutedEventArgs e) { DataTransferManager.ShowShareUI(); } }
何の変哲もない一般的な共有を行うためのコードです。説明も特に必要ないでしょう。
実際にデバッグで実行すると、ちゃんと共有のポップアップが表示されます。
適当に Skype を選んでみると、ちゃんと和歌山の社畜の画像が共有されました。
動作が確認できたので、今度はリリースビルドにして同じように共有を行ってみると、SetStorageItems を呼び出したタイミングで例外が投げられてしまい動作しなくなります。
MissingInteropDataException と言われても良くわからなかったです。ちなみに同じコードでも .NET Native のバージョンを下げると動作します。
自動生成されたコード内での問題はどうしようもない感じですね。
回避方法としては IEnumerable<StorageFile> を渡している部分を IEnumerable<IStorageItem> に変更すれば動きます。凄くバグっぽいですが、ひとまずは明示的に配列の型を指定して作ればよいみたいです。
// IEnumerable<IStorageItem> になれば良い request.Data.SetStorageItems(new IStorageItem[] { storageItem }, true); // これも勿論 OK //request.Data.SetStorageItems(new [] { (IStorageItem)storageItem }, true); // これも OK //request.Data.SetStorageItems(new List<IStorageItem> { storageItem }, true);
ジェネリックの共変性の扱いで今の .NET Native には問題があるのかもしれません。
コードを修正後にリリースビルドで確認してみると、ちゃんと共有のポップアップが表示されました。
Visual Studio Feedback で報告したので、いつか直るのかもしれませんが今はこれで対応しておきました。
和歌山の社畜の画像を使いたかっただけという疑惑もありますが、メモなので良しとします。