没有程序集的简单 WPF 应用程序中的 .NET 异常 "A strongly-named assembly is required"

.NET exception "A strongly-named assembly is required" in simple WPF app with no assemblies

我有一个小型 WPF 工具,它具有简单的 XAML 形式(见下文),不使用第 3 方库或控件。 运行 在 Windows XP 到 Windows 8.1 in .net 3.5

的 50 台机器上没有问题

当我在 Windows Server 2012 上启动它时,它运行良好(写入文件、显示 MessageBoxes)直到执行前进到 第一个 WPF表单 ,在 XAML 解析期间,它在 非用户代码加载(视觉主题)库时崩溃。

Windows Server 2012 视觉主题是否存在任何已知的 .NET 问题?

DispatcherUnhandledException:

System.Windows.Markup.XamlParseException: Failed object initialization (ISupportInitialize.EndInit).
 A strongly-named assembly is required. (Exception from HRESULT: 0x80131044)
 Error at object 'ButtonRun' in markup file 'FIS;component/windows/mainwindow.xaml'. ---> System.IO.FileLoadException: A strongly-named assembly is required. (Exception from HRESULT: 0x80131044)

   at System.Reflection.Assembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Assembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection)
   at System.Reflection.Assembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Assembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection)
   at System.Reflection.Assembly.InternalLoad(AssemblyName assemblyRef, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection)
   at System.Reflection.Assembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection)
   at System.Reflection.Assembly.Load(String assemblyString)
   at System.Windows.SystemResources.ResourceDictionaries.LoadExternalAssembly(Boolean classic, Boolean generic, Assembly& assembly, String& assemblyName)
   at System.Windows.SystemResources.ResourceDictionaries.LoadThemedDictionary(Boolean isTraceEnabled)
   at System.Windows.SystemResources.FindDictionaryResource(Object key, Type typeKey, ResourceKey resourceKey, Boolean isTraceEnabled, Boolean allowDeferredResourceReference, Boolean mustReturnDeferredResourceReference, Boolean& canCache)
   at System.Windows.SystemResources.FindResourceInternal(Object key, Boolean allowDeferredResourceReference, Boolean mustReturnDeferredResourceReference)
   at System.Windows.SystemResources.FindThemeStyle(DependencyObjectType key)
   at System.Windows.StyleHelper.GetThemeStyle(FrameworkElement fe, FrameworkContentElement fce)
   at System.Windows.FrameworkElement.UpdateThemeStyleProperty()
   at System.Windows.FrameworkElement.OnInitialized(EventArgs e)
   at System.Windows.FrameworkElement.TryFireInitialized()
   at System.Windows.FrameworkElement.EndInit()
   at System.Windows.Markup.BamlRecordReader.ElementEndInit(Object& element)
   --- End of inner exception stack trace ---
   at System.Windows.Markup.XamlParseException.ThrowException(String message, Exception innerException, Int32 lineNumber, Int32 linePosition, Uri baseUri, XamlObjectIds currentXamlObjectIds, XamlObjectIds contextXamlObjectIds, Type objectType)
   at System.Windows.Markup.XamlParseException.ThrowException(ParserContext parserContext, Int32 lineNumber, Int32 linePosition, String message, Exception innerException)
   at System.Windows.Markup.BamlRecordReader.ThrowExceptionWithLine(String message, Exception innerException)
   at System.Windows.Markup.BamlRecordReader.CreateInstanceFromType(Type type, Int16 typeId, Boolean throwOnFail)
   at System.Windows.Markup.BamlRecordReader.GetElementAndFlags(BamlElementStartRecord bamlElementStartRecord, Object& element, ReaderFlags& flags, Type& delayCreatedType, Int16& delayCreatedTypeId)
   at System.Windows.Markup.BamlRecordReader.BaseReadElementStartRecord(BamlElementStartRecord bamlElementRecord)
   at System.Windows.Markup.BamlRecordReader.ReadElementStartRecord(BamlElementStartRecord bamlElementRecord)
   at System.Windows.Markup.BamlRecordReader.ReadRecord(BamlRecord bamlRecord)
   at System.Windows.Markup.BamlRecordReader.Read(Boolean singleRecord)
   at System.Windows.Markup.TreeBuilderBamlTranslator.ParseFragment()
   at System.Windows.Markup.TreeBuilder.Parse()
   at System.Windows.Markup.XamlReader.LoadBaml(Stream stream, ParserContext parserContext, Object parent, Boolean closeStream)
   at System.Windows.Application.LoadBamlStreamWithSyncInfo(Stream stream, ParserContext pc)
   at System.Windows.Application.LoadComponent(Uri resourceLocator, Boolean bSkipJournaledProperties)
   at System.Windows.Application.DoStartup()
   at System.Windows.Application.<.ctor>b__0(Object unused)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)

简单的 XAML 表单,包括应用程序启动时的 WPF 启动画面(淡出):

<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Name="MainWin" Title="..........." Height="228" Width="525" WindowStartupLocation="CenterScreen" AllowsTransparency="True" WindowStyle="None" ResizeMode="CanMinimize" MouseLeftButtonDown="Window_MouseLeftButtonDown" MouseRightButtonDown="Window_MouseRightButtonDown" Loaded="Window_Loaded">
    <Window.Triggers>
        <EventTrigger RoutedEvent="Window.Loaded">
            <BeginStoryboard>
                <Storyboard>
                    <DoubleAnimation
                        Storyboard.TargetName="MainWin"
                        Storyboard.TargetProperty="(Window.Opacity)" 
                        From="0" To="1" Duration="0:0:0.5" />
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Window.Triggers>
    <Window.Background>
        <LinearGradientBrush EndPoint="0.5,1" MappingMode="RelativeToBoundingBox" StartPoint="0.5,0">
            <GradientStop Color="#CF767676" Offset="1"/>
            <GradientStop Color="#CF565656" Offset="0.5"/>
            <GradientStop Color="#CFB4B4B4"/>
        </LinearGradientBrush>
    </Window.Background>
    <Grid>
        <Image HorizontalAlignment="Center" Height="128" Margin="197.88,80.702,199.12,0" VerticalAlignment="Top" Width="128" Source="xxxxxxxxxx_128x128_png.png" Stretch="None" RenderTransformOrigin="0.575,0.541"/>
        <Button x:Name="ButtonRun" Content="......." HorizontalAlignment="Left" Margin="197.88,195.04,0,0" VerticalAlignment="Top" Width="129" Height="23" IsDefault="True"/>
        <Button x:Name="ButtonRunMenu" Content="....................." HorizontalAlignment="Left" Margin="377,195.04,0,0" VerticalAlignment="Top" Width="129" Height="23" IsDefault="True"/>
        <Button x:Name="ButtonMinimize" Content="0" Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}" HorizontalAlignment="Left" Margin="462,10,0,0" VerticalAlignment="Top" Width="24" Click="ButtonMinimize_Click" BorderThickness="0" Background="#00DDDDDD" Foreground="#FFEEEEEE" FontFamily="Marlett" FontSize="16" ToolTip="............."/>
        <Button x:Name="ButtonClose" Content="r" Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}" HorizontalAlignment="Left" Margin="491,10,0,0" VerticalAlignment="Top" Width="24" Click="ButtonClose_Click" IsCancel="True" BorderThickness="0" Background="#00DDDDDD" Foreground="#FFEEEEEE" FontFamily="Marlett" FontSize="16" ToolTip=".............."/>
        <Label x:Name="LabelAppName" Content="..." Margin="67.834,17.757,0,0" VerticalAlignment="Top" HorizontalContentAlignment="Center" Foreground="#FFEEEEEE" FontSize="20" HorizontalAlignment="Left" Width="389.166"/>
        <Label x:Name="LabelCurrentAction" Content="........................." HorizontalAlignment="Left" Margin="10,192.04,0,0" VerticalAlignment="Top" Foreground="#FFEEEEEE" Width="253.993"/>
        <Label x:Name="LabelPreparedVersion" Content="......" HorizontalAlignment="Center" Margin="10,47.779,10,0" VerticalAlignment="Top" Width="505" HorizontalContentAlignment="Center" Foreground="#FFEEEEEE"/>
        <Label x:Name="LabelErrorCondition" Content="............" HorizontalAlignment="Left" Height="26.261" Margin="0,60,0,0" VerticalAlignment="Top" Width="168" Background="#FFBB0000" Foreground="White"/>
        <Label x:Name="LabelWarningCondition" Content="..........." HorizontalAlignment="Left" Height="26.261" Margin="0,90,0,0" VerticalAlignment="Top" Width="168" Background="#FFDD8800"/>
        <Label x:Name="LabelNotAtLatestVersion" Content="........................" HorizontalAlignment="Left" Height="26.261" Margin="0,120,0,0" VerticalAlignment="Top" Width="168" Background="#FFCCCC00"/>
        <Label x:Name="LabelUpdatesNoConnection" Content=".................................." HorizontalAlignment="Left" Height="26.261" Margin="0,150,0,0" VerticalAlignment="Top" Width="208" Background="#FFDD8800"/>
        <Label x:Name="LabelUpdatesMisconfigured" Content="................................" HorizontalAlignment="Left" Height="26.261" Margin="0,150,0,0" VerticalAlignment="Top" Width="192.88" Background="#FFDD8800"/>
        <Label x:Name="LabelUpdatesDisabled" Content="............................" HorizontalAlignment="Left" Height="26.261" Margin="0,150,0,0" VerticalAlignment="Top" Width="168" Background="#FFCCCCCC"/>
        <Label x:Name="LabelUpdateAvailableForDownload" Content="............................" HorizontalAlignment="Left" Height="26.261" Margin="0,150,0,0" VerticalAlignment="Top" Width="168" Background="White"/>

    </Grid>
</Window>

更多详情:

为什么 .NET 会崩溃?

有没有强名称附加到项目的 ZIP DLL 库。 WPF 正在尝试扫描它。

当我检查 Solution explorer 工具 window 时,即项目引用列表和每个引用的检查属性(在 Properties window),我发现有引用的 ZIP DLL 库,其中 属性 Strong Name 设置为 False

问题仍然是为什么这会在 WPF 初始化时崩溃,但我想有两个原因:

  • 加载第一个 WPF 控件时使用反射扫描(甚至不相关的)项目库以查找它们是否包含 WPF 控件的外观

  • Windows 服务器为强程序集名称设置了比标准 Windows 机器更严格的策略

综上所述,可以理解为什么没有强名称的库仅在 Windows Server 2012 上导致 WPF 初始化期间崩溃。