-->

WPF window throws TypeInitializationException at s

2019-02-18 08:58发布

问题:

I have an Excel AddIn with several ribbons, one ribbon is setting window. When it is clicked, a custom window will show up. However, there is nothing to show up when clicked. I saw the following exceptions in log file. What causes this and how to fix it? thanks a lot

2012-04-09 09:59:50,161 [1] ERROR Helper [(null)] - Name:TypeInitializationException
Message:The type initializer for 'System.Windows.Window' threw an exception.
Target:Void .ctor()
Stack:   at System.Windows.Window..ctor()
   at MyShared.View.ConnectionSetup..ctor()
   at MyAddIn.Connect.GetSettings()
   at MyAddIn.Connect.BtnClick(IRibbonControl control)

Name:TypeInitializationException
Message:The type initializer for 'System.Windows.FrameworkElement' threw an exception.
Target:Void .cctor()
Stack:   at System.Windows.Window..cctor()

Name:TypeInitializationException
Message:The type initializer for 'System.Windows.Documents.TextElement' threw an exception.
Target:Void .cctor()
Stack:   at System.Windows.FrameworkElement..cctor()

Name:TypeInitializationException
Message:The type initializer for 'MS.Internal.FontCache.Util' threw an exception.
Target:Int32 get_Dpi()
Stack:   at MS.Internal.FontCache.Util.get_Dpi()
   at System.Windows.SystemFonts.ConvertFontHeight(Int32 height)
   at System.Windows.Documents.TextElement..cctor()

Name:UriFormatException
Message:Invalid URI: The format of the URI could not be determined.
Target:Void CreateThis(System.String, Boolean, System.UriKind)
Stack:   at System.Uri.CreateThis(String uri, Boolean dontEscape, UriKind uriKind)
   at System.Uri..ctor(String uriString, UriKind uriKind)
   at MS.Internal.FontCache.Util..cctor()

Edit, here is xaml code

<Window x:Class="MyShared.View.ConnectionSetup"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:toolkit="http://schemas.microsoft.com/wpf/2008/toolkit"
    xmlns:Converter="clr-namespace:MIMICShared.Converter" 
    WindowStartupLocation="CenterOwner"
    Title="Settings" Width="446" Height="650"  Closing="WindowClosing"
DataContextChanged="UserControlDataContextChanged" Foreground="Black" FontWeight="Normal" HorizontalAlignment="Stretch">
<Window.Resources>
    <ResourceDictionary>
        <Converter:Status2ImageConverter x:Key="string2Image"/>
    </ResourceDictionary>
</Window.Resources>

<Grid FocusManager.FocusedElement="{Binding ElementName=uname}" >
    <Grid.RowDefinitions>
        <RowDefinition Height="0"></RowDefinition>
        <RowDefinition Height="*"></RowDefinition>
        <RowDefinition Height="0"></RowDefinition>
        <RowDefinition Height="Auto"></RowDefinition>
        <RowDefinition Height="0"></RowDefinition>
        <RowDefinition Height="Auto"></RowDefinition>
        <RowDefinition Height="5"></RowDefinition>
    </Grid.RowDefinitions>
    <GroupBox Grid.Row="1" Foreground="Blue">
        <Grid >
            <Grid.ColumnDefinitions>                    
                <ColumnDefinition Width="5"></ColumnDefinition>
                <ColumnDefinition Width="*"></ColumnDefinition>
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="5"></ColumnDefinition>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="2"></RowDefinition>
                <RowDefinition Height="30"></RowDefinition>
                <RowDefinition Height="2"></RowDefinition>
                <RowDefinition Height="*"></RowDefinition>
                <RowDefinition Height="2"></RowDefinition>
                <RowDefinition Height="Auto"></RowDefinition>
                <RowDefinition Height="2"></RowDefinition>
                <RowDefinition Height="Auto"></RowDefinition>
                <RowDefinition Height="2"></RowDefinition>
                <RowDefinition Height="Auto"></RowDefinition>
                <RowDefinition Height="2"></RowDefinition>
            </Grid.RowDefinitions>
            <Label Grid.Row="1" Grid.ColumnSpan="4" FontSize="14" HorizontalAlignment="Center" FontWeight="Bold" VerticalAlignment="Bottom">Historical</Label>
            <GroupBox Grid.Column="1" Grid.Row="3" Header="Connections" Foreground="Blue" Grid.ColumnSpan="2">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="*" ></RowDefinition>
                        <RowDefinition Height="Auto"></RowDefinition>
                    </Grid.RowDefinitions>

                    <toolkit:DataGrid x:Name="connectionlist" Margin="5" Style="{DynamicResource DataGridStyleDefault}" Background="White"
              AutoGenerateColumns="False" HeadersVisibility="All"
              SelectionMode="Single"
              GridLinesVisibility="None"                  
              ItemsSource="{Binding SettingList}" CanUserAddRows="False" CanUserDeleteRows="True"
              SelectionUnit="FullRow" SelectedItem="{Binding SelectedItem}" 
              SelectionChanged="ConnectionlistSelectionChanged"                               
              VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled">
                        <!-- Column definition -->
                        <toolkit:DataGrid.Columns>
                            <!-- Pool -->
                            <!--<toolkit:DataGridCheckBoxColumn Header="Pool" Width="40" Binding="{Binding pool}" />-->
                            <!-- Connections info -->
                            <toolkit:DataGridTextColumn Header="Connection Info" Width="*" Binding="{Binding host}" />
                            <toolkit:DataGridTextColumn Header="Description" Width="*"  Binding="{Binding desc}" >
                                <toolkit:DataGridTextColumn.ElementStyle>
                                    <Style TargetType="{x:Type TextBlock}">
                                        <Setter Property="TextWrapping" Value="Wrap" />
                                    </Style>
                                </toolkit:DataGridTextColumn.ElementStyle>
                            </toolkit:DataGridTextColumn>
                        </toolkit:DataGrid.Columns>
                    </toolkit:DataGrid>

                    <Grid Grid.Row="2" HorizontalAlignment="Center">
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto"></ColumnDefinition>
                                <ColumnDefinition Width="Auto"></ColumnDefinition>
                            </Grid.ColumnDefinitions>
                            <Button Margin="2" Padding="10 0" x:Name="AddButton" Click="AddClicked">Add</Button>
                            <Button Grid.Column="1" Margin="2" Padding="10 0" Command="{Binding Remove}">Remove</Button>
                        </Grid>
                    </Grid>
                </Grid>
            </GroupBox>

            <GroupBox Header="Authentication" Grid.Row="5" Grid.Column="1" Foreground="Blue" Grid.ColumnSpan="2">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition  Height="Auto"/>
                        <RowDefinition  Height="2"/>
                        <RowDefinition  Height="Auto"/>
                        <RowDefinition  Height="2"/>
                        <RowDefinition  Height="Auto"/>
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition  Width="Auto"/>
                        <ColumnDefinition  Width="5"/>
                        <ColumnDefinition  Width="Auto"/>
                        <ColumnDefinition  Width="Auto"/>
                    </Grid.ColumnDefinitions>

                    <Label Grid.Row="0" Grid.Column="0">Username:</Label>
                    <TextBox x:Name="uname" Width="100" Grid.Row="0" Grid.Column="2" Text="{Binding UserName, UpdateSourceTrigger=PropertyChanged}" ></TextBox>

                    <Label Grid.Row="2" Grid.Column="0">Password:</Label>
                    <PasswordBox x:Name="pwd" ToolTip="Password" PasswordChar="*"                             
                         Width="100" Grid.Row="2" Grid.Column="2" KeyDown="OnKeyDownHandler"></PasswordBox>
                    <Label Grid.Row="2" Grid.Column="3">
                        <Hyperlink Click="HyperlinkClick">Forgot Password?</Hyperlink>
                    </Label>
                    <CheckBox Margin="10 0 0 0" Grid.Row="4" Grid.Column="0" Grid.ColumnSpan="2" x:Name="saveauth" IsChecked="{Binding SaveAuth}">Save username and password</CheckBox>
                    <Button Margin="10 0 0 0" Grid.Row="4" Grid.Column="3" Click="VerifyButtonClick">OK</Button>
                </Grid>
            </GroupBox>
            <GroupBox Header="Status" Grid.Row="7" Grid.Column="1" Foreground="Blue" Grid.ColumnSpan="2">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition  Height="0"/>
                        <RowDefinition  Height="Auto"/>
                        <RowDefinition  Height="0"/>
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition  Width="80"/>
                        <ColumnDefinition  Width="20"/>
                        <ColumnDefinition  Width="Auto"/>
                    </Grid.ColumnDefinitions>
                    <Label Grid.Row="1" Grid.Column="0">Historical</Label>
                    <Image Grid.Row="1" Grid.Column="1" 
                           Source="{Binding ElementName=historicalStatusLabel, Path=Content, Converter={StaticResource string2Image}}"
                           ToolTip="Connection Status"></Image>
                    <Label  Name="historicalStatusLabel" Grid.Row="1" Grid.Column="2" Content="{Binding ConnectionStatus, UpdateSourceTrigger=PropertyChanged}"/>
                </Grid>
            </GroupBox>
        </Grid>
    </GroupBox>
    <GroupBox Grid.Row="3" Grid.Column="1" Foreground="Blue">
        <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="0"></RowDefinition>
            <RowDefinition Height="30"></RowDefinition>
            <RowDefinition Height="0"></RowDefinition>
            <RowDefinition Height="Auto"></RowDefinition>
            <RowDefinition Height="0"></RowDefinition>
            <RowDefinition Height="Auto"></RowDefinition>
            <RowDefinition Height="0"></RowDefinition>
            <RowDefinition Height="Auto"></RowDefinition>
            <RowDefinition Height="0"></RowDefinition>
        </Grid.RowDefinitions>
            <Label Grid.Row="1" FontSize="14" FontWeight="Bold" HorizontalAlignment="Center" VerticalAlignment="Bottom">Real Time</Label>
                <GroupBox Header="Authorization" Grid.Row="3" Grid.Column="1" Foreground="Blue">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition  Height="Auto"/>
                <RowDefinition  Height="2"/>
                <RowDefinition  Height="Auto"/>
                <RowDefinition  Height="2"/>
                <RowDefinition  Height="Auto"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition  Width="Auto"/>
                <ColumnDefinition  Width="2"/>
                <ColumnDefinition  Width="Auto"/>
                <ColumnDefinition  Width="Auto"/>
            </Grid.ColumnDefinitions>

            <Label Grid.Row="0" Grid.Column="0">Username:</Label>
            <TextBox x:Name="RTDemail" Width="100" Grid.Row="0" Grid.Column="2" Text="{Binding RTDUserName, UpdateSourceTrigger=PropertyChanged}"></TextBox>

            <Label Grid.Row="2" Grid.Column="0">Password:</Label>
            <PasswordBox x:Name="RTDpwd" ToolTip="Password" PasswordChar="*"                             
                         Width="100" Grid.Row="2" Grid.Column="2" KeyDown="OnKeyDownHandler"></PasswordBox>
            <Label Grid.Row="2" Grid.Column="3">
                <Hyperlink Click="HyperlinkClickRTD">Forgot Password?</Hyperlink>
            </Label>
            <CheckBox Margin="10 0 0 0" Grid.Row="4" Grid.Column="0" Grid.ColumnSpan="2" x:Name="RTDsaveauth" IsChecked="{Binding RTDSaveAuth}">Save username and password</CheckBox>
            <Button Margin="10 0 0 0" Grid.Row="4" Grid.Column="3" Click="RTDVerifyButtonClick">OK</Button>
        </Grid>
    </GroupBox>
    <GroupBox Grid.Row="5" Grid.ColumnSpan="3">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="10"></ColumnDefinition>
                <ColumnDefinition Width="Auto"></ColumnDefinition>
                <ColumnDefinition Width="*"></ColumnDefinition>
            </Grid.ColumnDefinitions>
            <Label Grid.Column="1" Margin="0 0 0 0" Foreground="Blue">Server</Label>
            <Label Name="RTDServerURLLabel" Grid.Column="2" Content="{Binding RTDServerURL}"></Label>
        </Grid>
    </GroupBox>
    <GroupBox Header="Status" Grid.Row="7" Grid.Column="1" Foreground="Blue">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition  Height="2"/>
                <RowDefinition  Height="Auto"/>
                <RowDefinition  Height="2"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition  Width="80"/>
                <ColumnDefinition  Width="20"/>
                <ColumnDefinition  Width="Auto"/>
            </Grid.ColumnDefinitions>
            <Label Grid.Row ="1" Grid.Column="0">Real Time</Label>
            <Image Grid.Row ="1" Grid.Column="1" 
                    Source="{Binding ElementName=RTDStatusLabel, Path=Content, Converter={StaticResource string2Image}}"
                   ToolTip="Connection Status" HorizontalAlignment="Left" Width="20"></Image>
            <Label Name="RTDStatusLabel" Grid.Row="1" Grid.Column="2" Content="{Binding RTDConnectionStatus, UpdateSourceTrigger=PropertyChanged}"></Label>
        </Grid>
    </GroupBox>
    </Grid>
    </GroupBox>        
    <Grid Grid.Row="5" Grid.Column="0" Grid.ColumnSpan="3" >
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"></ColumnDefinition>
                <ColumnDefinition Width="60"></ColumnDefinition>
                <ColumnDefinition Width="20"></ColumnDefinition>
        </Grid.ColumnDefinitions>
            <Button x:Name="CloseButton" Click="CloseButtonClick" Grid.Column ="1" Margin="0,0,0,0">Close</Button>
        </Grid>                  
</Grid>

When ribbon is clicked, the code is executed, ConnectionSetup is the xaml file above

private bool GetSettings()
{
    var settingUI = new ConnectionSetup();
    settingUI.DataContext = Settings;

    CenterMainWindow(settingUI, wndHandle.Handle);

    bool? result = settingUI.ShowDialog();
    return result ?? false;
}

    private void CenterMainWindow(System.Windows.Window window, IntPtr ownerHandle)
    {
        var helper = new System.Windows.Interop.WindowInteropHelper(window) {Owner = ownerHandle};

        // Center window
        // Note - Need to use HwndSource to get handle to WPF owned window,
        //        and the handle only exists when SourceInitialized has been
        //        raised

        window.SourceInitialized += delegate
                                        {
                                            // Get WPF size and location for non-WPF owner window
                                            var nonWPFOwnerLeft = XLApp.Left;
                                            var nonWPFOwnerWidth = XLApp.Width;
                                            var nonWPFOwnerTop = XLApp.Top;
                                            var nonWPFOwnerHeight = XLApp.Height;

                                            // Get transform matrix to transform non-WPF owner window
                                            // size and location units into device-independent WPF
                                            // size and location units
                                            var source = System.Windows.Interop.HwndSource.FromHwnd(helper.Handle);
                                            if (source != null && source.CompositionTarget != null)
                                            {
                                                var matrix = source.CompositionTarget.TransformFromDevice;
                                                var ownerWPFSize =
                                                    matrix.Transform(new System.Windows.Point(nonWPFOwnerWidth,
                                                                                              nonWPFOwnerHeight));
                                                var ownerWPFPosition =
                                                    matrix.Transform(new System.Windows.Point(nonWPFOwnerLeft,
                                                                                              nonWPFOwnerTop));

                                                // Center WPF window
                                                window.WindowStartupLocation = WindowStartupLocation.Manual;
                                                window.Left = Math.Max(0,
                                                                       ownerWPFPosition.X +
                                                                       (ownerWPFSize.X - window.Width)/2);
                                                window.Top = Math.Max(0,
                                                                      ownerWPFPosition.Y +
                                                                      (ownerWPFSize.Y - window.Height)/2);
                                            }
                                        };
    }

回答1:

Judging from the error stack you posted, it appears that your settings window probably has a link on it. Unfortunately, the link has an invalid url in it, which causes the creation of the window to fail.

EDIT: Having looked more closely at your code and error messages, it's clear that I was looking in the wrong area. Some searching turned up a bug in wpf.

The short version: the windir environment variable may be set incorrectly on the target machine, which causes the font subsytem to break. The workaround is to fix the environment variable, either on the target machine's registry, or in the code by adding something like the following to the startup:

Environment.SetEnvironmentVariable("windir", Environment.GetEnvironmentVariable("SystemRoot"));


回答2:

We had a couple of people experience this problem. The solution described here (caused by PATH being greater than 2048 characters) resolved the issue.



回答3:

I am concerned that the statement suggested above may be problematic in code that is running with either too many or too few privileges. Certainly my app running with on my workstation with me as administrator has no issue with this call to Environment.SetEnvironmentVariable("windir",Environment.GetEnvironmentVariable("SystemRoot"));

but I am not sure that SetEnvironmentVariable will actually work on a locked-down OS. Has anybody a) tried this for real and b) tried it in a low-privilege environment>

Also, I am seeing some oddity on app startup after I install an app with this call, and run it once. All other applications no longer can see windir,which is not expanding to C:\Windows. I am going to go through the whole install and run without it in place and see if either the TypeInvocation exception resurfaces or if not, whether the OS windir variable is left intact.

UPDATE:

I have confirmed that the bad behavior I noticed was due to not specifying the target of the SetEnvironment call. Using the following my problems seem to have been alleviated:

System.Environment.SetEnvironmentVariable("windir", System.Environment.GetEnvironmentVariable("SystemRoot"), EnvironmentVariableTarget.User);

When I did not set the target, very odd things happened to my Windows session requiring me to either logoff and login or even reboot. So unless this change is really to be at the machine or process level, do not assume happy results with the default