MSDN.WhiteKnight - Stack Overflow answers
Ответ на "При попытке указать `MediaElement`у `Source` где `Uri` будет начинаться с `https://`, получаем исключение?"
Answer 924970
Если отключить в студии режим "Только мой код" в настройках отладчика, можно получить стек, вызывающий данное исключение:
PresentationCore.dll!System.Windows.Media.MediaPlayerState.OpenMedia(System.Uri source) + 0x10d bytes PresentationCore.dll!System.Windows.Media.MediaPlayerState.SetSource(System.Uri source) + 0x27 bytes PresentationCore.dll!System.Windows.Media.MediaPlayerState.Open(System.Uri source) + 0x27 bytes PresentationFramework.dll!System.Windows.Controls.AVElementHelper.HandleStateChange() + 0x240 bytes PresentationFramework.dll!System.Windows.Controls.AVElementHelper.MemberOnInvalidateSource(System.Windows.DependencyPropertyChangedEventArgs e) + 0x5b bytes PresentationFramework.dll!System.Windows.Controls.AVElementHelper.OnSourceChanged(System.Windows.DependencyObject d, System.Windows.DependencyPropertyChangedEventArgs e) + 0x67 bytes WindowsBase.dll!System.Windows.DependencyObject.OnPropertyChanged(System.Windows.DependencyPropertyChangedEventArgs e) + 0x83 bytes PresentationFramework.dll!System.Windows.FrameworkElement.OnPropertyChanged(System.Windows.DependencyPropertyChangedEventArgs e) + 0x9f bytes WindowsBase.dll!System.Windows.DependencyObject.NotifyPropertyChange(System.Windows.DependencyPropertyChangedEventArgs args) + 0x64 bytes WindowsBase.dll!System.Windows.DependencyObject.UpdateEffectiveValue(System.Windows.EntryIndex entryIndex, System.Windows.DependencyProperty dp, System.Windows.PropertyMetadata metadata, System.Windows.EffectiveValueEntry oldEntry, ref System.Windows.EffectiveValueEntry newEntry, bool coerceWithDeferredReference, bool coerceWithCurrentValue, System.Windows.OperationType operationType) + 0x853 bytes WindowsBase.dll!System.Windows.DependencyObject.SetValueCommon(System.Windows.DependencyProperty dp, object value, System.Windows.PropertyMetadata metadata, bool coerceWithDeferredReference, bool coerceWithCurrentValue, System.Windows.OperationType operationType, bool isInternal) + 0x3f7 bytes WindowsBase.dll!System.Windows.DependencyObject.SetValue(System.Windows.DependencyProperty dp, object value) + 0x52 bytes WpfApplication1.exe!WpfApplication1.MainWindow.Button_Click_1(object sender, System.Windows.RoutedEventArgs e) Line 31 + 0x42 bytes
Далее, глядя в код метода OpenMedia, видим, что в случае, когда передаваемый URI имеет схему https, .NET пытается получить URI публикации для текущего приложения и далее, если этот URI не https, проделать некие телодвижения с целью проверки "безопасно ли сделать это в данном контексте". Но проблема в том, что URI публикации определен только в двух случаях: для браузерного WPF и для приложений ClickOnce. В остальных случаях этот URI будет иметь значение null, и, так как это не проверяется, имеем NRE.
Иными словами, как правильно заметил в комментариях demonplus, это обыкновенный баг в WPF. Как его обойти? Ну, самое простое, это перейти с MediaElement на что-то другое, например на ActiveX-элемент Windows Media Player, который обладает тем же функционалом, но избавлен от этой проблемы. Не то, чтобы MediaElement из WPF обладал какими-то особыми преимуществами. Однако, если вам действительно нужен MediaElement, можете воспользоваться следующим грязным хаком для принудительной установки URI публикации:
Assembly assPresentationCore = typeof(UIElement).Assembly; //PresentationCore.dll Assembly assWindowsBase = typeof(System.Windows.Vector).Assembly; //WindowsBase.dll //найдем информацию о типах Type typeContainer = assPresentationCore.GetType("MS.Internal.AppModel.SiteOfOriginContainer"); Type typeDS = assWindowsBase.GetType("MS.Internal.SecurityCriticalDataForSet`1").MakeGenericType(typeof(Uri)); Type typeNullable = typeof(Nullable<int>).GetGenericTypeDefinition().MakeGenericType(typeDS); //найдем информацию о необходимом закрытом поле FieldInfo field = typeContainer.GetField("_siteOfOriginForClickOnceApp", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static ); //создадим объект Nullable<MS.Internal.SecurityCriticalDataForSet<Uri>> object objDS = Activator.CreateInstance(typeDS, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, null, new object[] { new Uri("http://localhost/") }, System.Globalization.CultureInfo.InvariantCulture ); object objNullable = Activator.CreateInstance(typeNullable, objDS); //установим значение поля field.SetValue(null, objNullable);
Обновление: Данная ошибка была исправлена в WPF для .NET Core 3.1. Метод OpenMedia больше не обращается к SecurityHelper.ExtractUriForClickOnceDeployedApp, и MediaElement теперь работает с https://
Content is retrieved from StackExchange API.
Auto-generated by ruso-archive tools.