question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Combination of `PublishSingleFile` and `PublishReadyToRun` prevents app from starting

See original GitHub issue

Problem description

Since changing the TargetFramework in our .csproj file from net6.0-windows to net7.0-windows our app crashes upon starting with a System.TypeInitializationException thrown in the initializer for System.Windows.Media.FontFamily.

Removing either the PublishSingleFile or the PublishReadyToRun tag from the projects .csproj file (or switching back to net6.0-windows) fixes the problem.

Stack-trace

System.TypeInitializationException: The type initializer for 'System.Windows.Media.FontFamily' threw an exception.
 ---> System.TypeInitializationException: The type initializer for 'MS.Internal.FontCache.DWriteFactory' threw an exception.
 ---> System.InvalidCastException: Specified cast is not valid.
   at MS.Internal.Text.TextInterface.Native.Util.ConvertHresultToException(Int32 hr)
   at MS.Internal.Text.TextInterface.Factory.Initialize(FactoryType factoryType)
   at MS.Internal.Text.TextInterface.Factory..ctor(FactoryType factoryType, IFontSourceCollectionFactory fontSourceCollectionFactory, IFontSourceFactory fontSourceFactory)
   at MS.Internal.FontCache.DWriteFactory..cctor()
   --- End of inner exception stack trace ---
   at MS.Internal.FontCache.DWriteFactory.get_SystemFontCollection()
   at System.Windows.Media.FontFamily..cctor()
   --- End of inner exception stack trace ---
   at MS.Internal.Text.DynamicPropertyReader.GetTypeface(DependencyObject element)
   at MS.Internal.Text.TextProperties.InitCommon(DependencyObject target)
   at MS.Internal.Text.TextProperties..ctor(FrameworkElement target, Boolean isTypographyDefaultValue)
   at System.Windows.Controls.TextBoxView.GetLineProperties()
   at System.Windows.Controls.TextBoxView.TextCache..ctor(TextBoxView owner)
   at System.Windows.Controls.TextBoxView.MeasureOverride(Size constraint)
   at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at MS.Internal.Helper.MeasureElementWithSingleChild(UIElement element, Size constraint)
   at System.Windows.Controls.ScrollContentPresenter.MeasureOverride(Size constraint)
   at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at System.Windows.Controls.Grid.MeasureCell(Int32 cell, Boolean forceInfinityV)
   at System.Windows.Controls.Grid.MeasureCellsGroup(Int32 cellsHead, Size referenceSize, Boolean ignoreDesiredSizeU, Boolean forceInfinityV, Boolean& hasDesiredSizeUChanged)
   at System.Windows.Controls.Grid.MeasureOverride(Size constraint)
   at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at System.Windows.Controls.ScrollViewer.MeasureOverride(Size constraint)
   at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at System.Windows.Controls.Border.MeasureOverride(Size constraint)
   at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at System.Windows.Controls.Control.MeasureOverride(Size constraint)
   at System.Windows.Controls.TextBox.MeasureOverride(Size constraint)
   at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at System.Windows.Controls.Grid.MeasureOverride(Size constraint)
   at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at MS.Internal.Helper.MeasureElementWithSingleChild(UIElement element, Size constraint)
   at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at System.Windows.Controls.Decorator.MeasureOverride(Size constraint)
   at System.Windows.Documents.AdornerDecorator.MeasureOverride(Size constraint)
   at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at System.Windows.Controls.Border.MeasureOverride(Size constraint)
   at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at System.Windows.Window.MeasureOverrideHelper(Size constraint)
   at System.Windows.Window.MeasureOverride(Size availableSize)
   at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at System.Windows.Interop.HwndSource.SetLayoutSize()
   at System.Windows.Interop.HwndSource.set_RootVisualInternal(Visual value)
   at System.Windows.Window.SetRootVisualAndUpdateSTC()
   at System.Windows.Window.SetupInitialState(Double requestedTop, Double requestedLeft, Double requestedWidth, Double requestedHeight)
   at System.Windows.Window.CreateSourceWindow(Boolean duringShow)
   at System.Windows.Window.ShowHelper(Object booleanBox)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
   at System.Windows.Threading.DispatcherOperation.InvokeImpl()
   at MS.Internal.CulturePreservingExecutionContext.CallbackWrapper(Object obj)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
   at MS.Internal.CulturePreservingExecutionContext.Run(CulturePreservingExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Windows.Threading.DispatcherOperation.Invoke()
   at System.Windows.Threading.Dispatcher.ProcessQueue()
   at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
   at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
   at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
   at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
   at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
   at System.Windows.Application.RunDispatcher(Object ignore)
   at System.Windows.Application.RunInternal(Window window)
   at MyProject.App.Main()

Expected behavior

The app starts the same way it did when using net6.0-windows as TargetFramework.

net48

No idea whether this also reproduces in .NET Framework 4.8. We’re using net7.0 exclusively.

Relation to Visual Studio (or other tooling)

None. We did our testing using the dotnet publish command.

dotnet info:

.NET SDK:
 Version:   7.0.100
 Commit:    e12b7af219

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.19044
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\7.0.100\
 
...

Environment variables:
  Not set

global.json file:
  Not found
Minimal reproduction

There are no Directory.Build.props or Directory.Packages.props files present.

Executing the project results in a file named ex.txt with the stack-trace being left in the execution directory.

Project.csproj

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net7.0-windows</TargetFramework>
  </PropertyGroup>

  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <UseWPF>true</UseWPF>
  </PropertyGroup>

  <PropertyGroup>
    <PublishSingleFile>true</PublishSingleFile>
    <PublishReadyToRun>true</PublishReadyToRun>
  </PropertyGroup>
</Project>

App.xaml

<Application x:Class="MyProject.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="TestView.xaml"/>

App.xaml.cs

using System;
using System.IO;
using System.Windows;

namespace MyProject;

public sealed partial class App
{
    protected override void OnStartup(StartupEventArgs e)
    {
        AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;

        base.OnStartup(e);
    }

    private void OnUnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        ArgumentNullException.ThrowIfNull(e);
        ArgumentNullException.ThrowIfNull(e.ExceptionObject);

        Exception exception = (Exception)e.ExceptionObject;

        File.WriteAllText("ex.txt", exception.ToString());

        Environment.Exit(byte.MaxValue);
    }
}

TestView.xaml

<Window x:Class="MyProject.TestView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        mc:Ignorable="d">
    <Grid>
        <TextBox Text="Test"/>
    </Grid>
</Window>

TestView.xaml.cs

namespace MyProject;

public partial class TestView
{
    public TestView() => InitializeComponent();
}

special thanks to @beagle1986 for lending me his ear.

Issue Analytics

  • State:open
  • Created 10 months ago
  • Reactions:10
  • Comments:11 (2 by maintainers)

github_iconTop GitHub Comments

2reactions
ThomasGoulet73commented, Feb 9, 2023

@Mathyn I believe this issue is being tracked in dotnet/runtime#65879. Starting with .Net 7.0, R2R uses Composite mode by default when also using Single-file (See dotnet/sdk#25963).

As a workaround, you can disable Composite mode by adding this to your csproj:

<PropertyGroup>
  <PublishReadyToRunComposite>false</PublishReadyToRunComposite>
</PropertyGroup>
1reaction
EgemenCiftcicommented, Dec 22, 2022

@dragnilar No. There are no fancy things. The bug can be reproduced with a default WPF app with a TextBlock on the MainWindow.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Create a single file for application deployment - .NET
The single file deployment option can be combined with ReadyToRun and Trim publish options. [IMPORTANT] To run a single file app on Windows...
Read more >
dotnet publish command - .NET CLI
The following MSBuild properties change the output of dotnet publish . PublishReadyToRun. Compiles application assemblies as ReadyToRun (R2R) ...
Read more >
PublishSingleFile does not produce a single executable
I have a .Net Core 3 console application that i'm trying to publish as a self contained single executable. I've been able to...
Read more >
Making a tiny .NET Core 3.0 entirely self-contained single ...
If you want, you can combine this "PublishedTrimmed" object with "PublishReadyToRun" as well and get a small AND fast app. < Project Sdk...
Read more >
.NET 5.0 Runtime Highlights
This set of dotnet commands and the extra information shown for size and startup performance demonstrates how to publish single file apps and...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found