AvaloniaUI / Avalonia

Develop Desktop, Embedded, Mobile and WebAssembly apps with C# and XAML. The most popular .NET UI client technology
https://avaloniaui.net
MIT License
25.56k stars 2.21k forks source link

Unable to run published Avalonia app #1665

Closed RayyanTahir closed 3 years ago

RayyanTahir commented 6 years ago

A repro of the issue can be found here

I have a window with an Image control that renders a PNG from Assets folder. When I run the application from visual studio the Image renders fine on the window, but when I publish the dotnet app in Windows OS and run the exe, the application fails to start. I found the issue after doing dotnet Applicationname.dll and got the following exception:

Unhandled Exception: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> Portable.Xaml.XamlObjectWriterException: Could not convert object 'resm:DotnetPublishRepro.Assets.logo.png' (of type System.String) to {clr-namespace:Avalonia.Media.Imaging;assembly=Avalonia.Visuals}IBitmap: The type initializer for 'SkiaSharp.SKManagedStream' threw an exception. ---> System.TypeInitializationException: The type initializer for 'SkiaSharp.SKManagedStream' threw an exception. ---> System.DllNotFoundException: Unable to load DLL 'libSkiaSharp': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
   at SkiaSharp.SkiaApi.sk_managedstream_set_delegates(IntPtr pRead, IntPtr pPeek, IntPtr pIsAtEnd, IntPtr pRewind, IntPtr pGetPosition, IntPtr pSeek, IntPtr pMove, IntPtr pGetLength, IntPtr pCreateNew, IntPtr pDestroy)
   at SkiaSharp.SKManagedStream..cctor()
   --- End of inner exception stack trace ---
   at Avalonia.Skia.PlatformRenderInterface.LoadBitmap(Stream stream)
   at Avalonia.Media.Imaging.Bitmap..ctor(Stream stream)
   at Avalonia.Markup.Xaml.Converters.BitmapTypeConverter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value)
   at Portable.Xaml.XamlObjectWriterInternal.GetCorrectlyTypedValue(XamlMember xm, XamlType xt, Object value)
   --- End of inner exception stack trace ---
   at Portable.Xaml.XamlObjectWriterInternal.GetCorrectlyTypedValue(XamlMember xm, XamlType xt, Object value)
   at Portable.Xaml.XamlObjectWriterInternal.StoreAppropriatelyTypedValue(ObjectState state, MemberAndValue ms, Object obj, Object keyObj)
   at Portable.Xaml.XamlObjectWriterInternal.OnWriteValue(Object value)
   at Portable.Xaml.XamlObjectWriter.WriteValue(Object value)
   at Portable.Xaml.XamlWriter.WriteNode(XamlReader reader)
   at Portable.Xaml.XamlServices.Transform(XamlReader xamlReader, XamlWriter xamlWriter, Boolean closeWriter)
   at Avalonia.Markup.Xaml.AvaloniaXamlLoaderPortableXaml.LoadFromReader(XamlReader reader, AvaloniaXamlContext context)
   at Avalonia.Markup.Xaml.AvaloniaXamlLoaderPortableXaml.Load(Stream stream, Object rootInstance, Uri uri)
   at Avalonia.Markup.Xaml.AvaloniaXamlLoaderPortableXaml.Load(Type type, Object rootInstance)
   at Avalonia.Markup.Xaml.AvaloniaXamlLoaderPortableXaml.Load(Object obj)
   at DotnetPublishRepro.MainWindow.InitializeComponent() in C:\Users\Rayyan\Desktop\AvaloniaRepros\DotnetPublishRepro\MainWindow.xaml.cs:line 19
   at DotnetPublishRepro.MainWindow..ctor() in C:\Users\Rayyan\Desktop\AvaloniaRepros\DotnetPublishRepro\MainWindow.xaml.cs:line 11
   --- End of inner exception stack trace ---
   at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor)
   at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)
   at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)
   at System.Activator.CreateInstance[T]()
   at Avalonia.Controls.AppBuilderBase`1.Start[TMainWindow](Func`1 dataContextProvider)
   at DotnetPublishRepro.Program.Main(String[] args) in C:\Users\Rayyan\Desktop\AvaloniaRepros\DotnetPublishRepro\Program.cs:line 11
MonkAlex commented 6 years ago

Unable to load DLL 'libSkiaSharp'

has this lib in app folder?

RayyanTahir commented 6 years ago

I don't see libSkiaSharp dll in any of the published files, even in publish folder.

byme8 commented 6 years ago

Any news?

MV10 commented 6 years ago

In a very simple project (the "Hello World" button from the Quick Start but set for .NET Core only) my top-level exception is the one that reports unable to load libSkiaSharp.dll. I get this publishing from VS2017 targeting win-x64 portable + Framework-dependent, so I tried publishing as self-contained but it still throws the same error. SkiaSharp.dll is in the stand-alone publish folder, but libSkiaSharp.dll is not.

I thought this might be one of those NuGet transient-dependency problems, but even if I added a reference to the SkiaSharp package (version 1.57.1, same as Avalonia uses right now) and re-published as self-contained, the DLL still isn't published.

I'm wondering if it's a mismatch with SkiaSharp's NuGet package runtime list. VS is using win-x64 but SkiaSharp's runtime folder lists win7-x64 and win10-x64.

danwalmsley commented 6 years ago

Are you using the nightly builds?

byme8 commented 6 years ago

I replaced win-x64 with win10-x64 and it works now

MV10 commented 6 years ago

This is probably a documentation issue, ultimately -- both here and for SkiaSharp (I'll open an issue over there and cross-reference this). By default, VS Publish only lists the fallback runtime IDs which is why I only saw the less-specific win-x64 target. NuGet can fallback from more-specific to less-specific, but not the other way around. To get a more-specific RID like win10-x64 in Visual Studio I added a <RuntimeIdentifiers> node to the csproj file:

<RuntimeIdentifiers>win10-x64;osx;linux-x64</RuntimeIdentifiers>

After this change, both the win10-x64 and the linux-x64 targets publish correctly (and probably somebody working on Avalonia has already thought about this issue given the existence of the avalonia.skia.linux.natives NuGet package).

However, publishing to the osx target still does not work, even though I see osx listed in SkiaSharp's nuget package.

I'm new to Avalonia (and I understand Avalonia is still very much a work-in-progress), should I expect OSX to build and publish yet?

danwalmsley commented 6 years ago

@byme8 you should use win7-x64, win-x64 is actually for targeting win-rt which isn't officially supported.

MV10 commented 6 years ago

@danwalmsley Just for the record, that isn't what win-x64 means. In the runtime ID docs I linked above, check out how it works in the RID graph -- it's what NuGet calls a fallback RID for when you want to publish to a version-specific target (like win7 or win10), but the library itself is not version-specific. I ran across a blog article yesterday, VS defaults to the less-specific fallback IDs because they want to encourage those over version-specific IDs wherever possible. (It's particularly messy when you consider the explosion of Linux RIDs.)

WinRT doesn't have an RID -- you can't use it as a publish target (which makes sense, as it has been discontinued). CoreRT is the new runtime targeting AOT (ahead-of-time compile) scenarios -- basically taking over from WinRT as Microsoft's end-game of getting rid of the Win32 API once and for all.

The first section of that article defines the full RID format as [os].[version]-[architecture]-[additional qualifiers] and one of the examples of an additional qualifier is corert so publishing for CoreRT would look like win-x64-corert.

You could confirm this with a self-contained publish targeting one of the version-specific Linux RIDs. You should still get the Linux version of libSkiaSharp because the avalonia.skia.linux.natives package specifies the linux-x64 fallback RID -- the next one down the graph that is selected if a version-specific implementation can't be found.

drearyrainDeng commented 5 years ago

build environment: win10 v1809 x64.
build ControlCatalog.Desktop app ok, but run fail (outputfolder with skiasharp.dll but no libSkiaSharp.dll)! after i copy it from "nuget\skiasharp\1.68.0\runtimes\win-x64\native" it will run normal!

grokys commented 3 years ago

Closing this because the original repro is no longer available.