WPF RichTextBox SpellCheck ComException

时间秒杀一切 提交于 2019-12-08 17:00:55

问题


I've got an exception while trying to enable spell checking on some Windows 8.1 machines (both have latest updates, OS language is russian and .NET framework 4.7 is russian) saying:

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Runtime.InteropServices.COMException: Invalid value for registry (Exception from HRESULT: 0x80040153 (REGDB_E_INVALIDVALUE)) at System.StubHelpers.StubHelpers.GetWinRTFactoryObject(IntPtr pCPCMD) at Windows.Data.Text.WordsSegmenter..ctor(String language) --- End of inner exception stack trace --- at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor) at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) at MS.Internal.WindowsRuntime.ReflectionHelper.ReflectionNew[TArg1](Type type, TArg1 arg1) at MS.Internal.WindowsRuntime.Windows.Data.Text.WordsSegmenter..ctor(String language) at MS.Internal.WindowsRuntime.Windows.Data.Text.WordsSegmenter.Create(String language, Boolean shouldPreferNeutralSegmenter) at System.Windows.Documents.WinRTSpellerInterop.EnsureWordBreakerAndSpellCheckerForCulture(CultureInfo culture, Boolean throwOnError) at System.Windows.Documents.WinRTSpellerInterop..ctor() at System.Windows.Documents.SpellerInteropBase.CreateInstance() at System.Windows.Documents.Speller.EnsureInitialized() at System.Windows.Documents.Speller.SetCustomDictionaries(CustomDictionarySources dictionaryLocations, Boolean add) at System.Windows.Documents.TextEditor.SetCustomDictionaries(Boolean add) at System.Windows.Controls.SpellCheck.OnIsEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) at System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e) at System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e) at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args) at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType) at System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, Object value, PropertyMetadata metadata, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType, Boolean isInternal) at System.Windows.DependencyObject.SetValue(DependencyProperty dp, Object value)

This code can be used to reproduce the issue:

var richTextBox = new RichTextBox();
InputLanguageManager.SetInputLanguage(richTextBox,CultureInfo.GetCultureInfo("en-US"));
richTextBox.SetValue(SpellCheck.IsEnabledProperty, true);

While investigation this issue I found that exception is thrown from s_WinRTType.ReflectionNew<string>(language); where s_WinRTType describes type "Windows.Data.Text.WordsSegmenter, Windows, ContentType=WindowsRuntime. WordsSegmenter seems to be WinRT component so I can't see what's going on inside it. I want to know why does it throw REGDB_E_INVALIDVALUE / which value it looks for and how should it look like? Thank you!

Update 1. I also saw this component's key exists in registry: So probably this component throws exception by itself


回答1:


You need to install the language features which is different from a language pack via control panel or using DISM. For me this required .Net 4.7 and is working for windows 10 build 1709 (fall creators update). I don't know if this is possible on Windows 8.

If you have proper access to windows update (not behind WSUS) you could try to install it

Dism /Online /Add-Capability /CapabilityName:Language.Basic~~~en-US~0.0.1.0

To check the installed features this shows all installed options:

dism /online /get-capabilities /limitaccess

Background info:

https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/add-language-packs-to-windows

https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/dism-capabilities-package-servicing-command-line-options

https://blogs.technet.microsoft.com/mniehaus/2015/08/31/adding-features-including-net-3-5-to-windows-10/

This last link explaines there is another version 2 of features on demand. For me it solved an issue.

Using the feature-on-demand isos (downloaded them from your msdn subscription):

for windows 10 (don't know if this is available on windows 8): en_windows_10_features_on_demand_part_1_version_1709_updated_sept_2017_x64_dvd_100090755 en_windows_10_features_on_demand_part_2_version_1709_updated_sept_2017_x64_dvd_100090754

extract them and install:

dism /online /add-package /packagepath:d:\features\Microsoft-Windows-LanguageFeatures-Basic-en-us-Package.cab

PS: did you Google for REGDB_E_INVALIDVALUE: VSHost crash, REGDB_E_INVALIDVALUE loading Specific Project

EXAMPLE:

You can create a wpf test application with the following code: This reads the AvailableInputLanguages that can be used. (for me it doesn't show the 4 languages from .Net 4 only the ones I install with Dism.

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <ComboBox 
          ItemsSource="{Binding AvailableLanguages}"
          SelectionChanged="OnLanguageSelectionChanged"
          DisplayMemberPath="NativeName"/>
    <TextBox x:Name="textBox" Grid.Row="1"
         AcceptsReturn="True"
         AcceptsTab="True"
         SpellCheck.IsEnabled="True"
         Text="Hello world"/>
</Grid>

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        AvailableLanguages = new ObservableCollection<CultureInfo>();

        foreach (CultureInfo culterInfo in InputLanguageManager.Current.AvailableInputLanguages)
        {
            AvailableLanguages.Add(culterInfo);
        }

        DataContext = this;
    }

    public ObservableCollection<CultureInfo> AvailableLanguages
    {
        get { return (ObservableCollection<CultureInfo>)GetValue(AvailableLanguagesProperty); }
        set { SetValue(AvailableLanguagesProperty, value); }
    }

    public static readonly DependencyProperty AvailableLanguagesProperty = DependencyProperty.Register("AvailableLanguages", typeof(ObservableCollection<CultureInfo>), typeof(MainWindow));


    private void OnLanguageSelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        CultureInfo xmlLanguage = e.AddedItems[0] as CultureInfo;
        textBox.Language = XmlLanguage.GetLanguage(xmlLanguage.Name);
    }
}


来源:https://stackoverflow.com/questions/49924503/wpf-richtextbox-spellcheck-comexception

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!