hardkoded/puppeteer-sharp

Failed to connect to browser when used in native AOT app

cfbao opened this issue · 4 comments

Description

Cannot launch & connect to browser when used in native AOT app.

Complete minimal example reproducing the issue

<!-- PuppeteerSharpRepro.csproj -->
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <PublishAoT>true</PublishAoT>
    <InvariantGlobalization>true</InvariantGlobalization>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="PuppeteerSharp" Version="19.0.0" />
  </ItemGroup>

</Project>
// Program.cs
await using var browser = await PuppeteerSharp.Puppeteer.LaunchAsync(new()
{
    ExecutablePath = @"C:\Program Files\Google\Chrome\Application\chrome.exe",
});

Publish this as a standalone executable (e.g. dotnet publish -r win-x64 -o build), then run the executable.

Expected behavior:

A Chrome browser process is launched and connected. No exception thrown.

Actual behavior:

A Chrome browser process is launched, but failed to connect.
Exception thrown:

Unhandled Exception: PuppeteerSharp.ProcessException: Failed to create connection
 ---> PuppeteerSharp.TargetClosedException: Protocol error(Target.setDiscoverTargets): Target closed. (Connection failed to process {"method":"Target.targetCreated","params":{"targetInfo":{"targetId":"C85F13952BD79831CE22166B365FD597","type":"page","title":"","url":"about:blank","attached":false,"canAccessOpener":false,"browserContextId":"A32BA6E4328CEC53068617EF44034A7F"}}}. 'PuppeteerSharp.Helpers.Json.JsonStringEnumMemberConverter+EnumMemberConverter`1[PuppeteerSharp.TargetType]' is missing native code or metadata. This can happen for code that is not compatible with trimming or AOT. Inspect and fix trimming and AOT related warnings that were generated when the app was published. For more information see https://aka.ms/nativeaot-compatibility.    at System.Reflection.Runtime.General.TypeUnifier.WithVerifiedTypeHandle(RuntimeConstructedGenericTypeInfo, RuntimeTypeInfo[]) + 0x75
   at PuppeteerSharp.Helpers.Json.JsonStringEnumMemberConverter.CreateConverter(Type, JsonSerializerOptions) + 0x98
   at PuppeteerSharp.Helpers.Json.SystemTextJsonSerializationContext.ExpandConverter(Type, JsonConverter, JsonSerializerOptions, Boolean) + 0x50
   at PuppeteerSharp.Helpers.Json.SystemTextJsonSerializationContext.TryGetTypeInfoForRuntimeCustomConverter[TJsonMetadataType](JsonSerializerOptions, JsonTypeInfo`1&) + 0x23
   at PuppeteerSharp.Helpers.Json.SystemTextJsonSerializationContext.Create_TargetType(JsonSerializerOptions) + 0x20
   at System.Text.Json.JsonSerializerOptions.GetTypeInfoNoCaching(Type) + 0x4e
   at System.Text.Json.JsonSerializerOptions.CachingContext.CreateCacheEntry(Type type, JsonSerializerOptions.CachingContext context) + 0x1d
--- End of stack trace from previous location ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20
   at System.Text.Json.JsonSerializerOptions.CachingContext.CacheEntry.GetResult() + 0x1e
   at System.Text.Json.JsonSerializerOptions.GetTypeInfoInternal(Type, Boolean, Nullable`1, Boolean, Boolean) + 0x3c
   at System.Text.Json.Serialization.Metadata.JsonPropertyInfo.Configure() + 0x7d
   at System.Text.Json.Serialization.Metadata.JsonTypeInfo.ConfigureProperties() + 0xf4
   at System.Text.Json.Serialization.Metadata.JsonTypeInfo.Configure() + 0x8c
   at System.Text.Json.Serialization.Metadata.JsonTypeInfo.<EnsureConfigured>g__ConfigureSynchronized|172_0() + 0xea
   at System.Text.Json.JsonSerializerOptions.GetTypeInfoInternal(Type, Boolean, Nullable`1, Boolean, Boolean) + 0x5a
   at System.Text.Json.Serialization.Metadata.JsonPropertyInfo.Configure() + 0x7d
   at System.Text.Json.Serialization.Metadata.JsonTypeInfo.ConfigureProperties() + 0xf4
   at System.Text.Json.Serialization.Metadata.JsonTypeInfo.Configure() + 0x8c
   at System.Text.Json.Serialization.Metadata.JsonTypeInfo.<EnsureConfigured>g__ConfigureSynchronized|172_0() + 0xea
   at System.Text.Json.JsonSerializerOptions.GetTypeInfoInternal(Type, Boolean, Nullable`1, Boolean, Boolean) + 0x5a
   at System.Text.Json.JsonSerializerOptions.GetTypeInfoForRootType(Type, Boolean) + 0x62
   at System.Text.Json.JsonSerializer.GetTypeInfo[T](JsonSerializerOptions) + 0x25
   at System.Text.Json.JsonSerializer.Deserialize[TValue](JsonElement, JsonSerializerOptions) + 0x33
   at PuppeteerSharp.Cdp.Connection.ProcessIncomingMessage(ConnectionResponse) + 0xb0
   at PuppeteerSharp.Cdp.Connection.<ProcessMessage>d__68.MoveNext() + 0x1fd)
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b
   at PuppeteerSharp.Helpers.TaskHelper.<WithTimeout>d__12`1.MoveNext() + 0x1d9
--- End of stack trace from previous location ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b
   at PuppeteerSharp.Cdp.Connection.<SendAsync>d__53.MoveNext() + 0x2bf
--- End of stack trace from previous location ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b
   at PuppeteerSharp.Cdp.ChromeTargetManager.<InitializeAsync>d__27.MoveNext() + 0x19c
--- End of stack trace from previous location ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b
   at PuppeteerSharp.Cdp.CdpBrowser.<CreateAsync>d__18.MoveNext() + 0x159
--- End of stack trace from previous location ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20
   at PuppeteerSharp.Cdp.CdpBrowser.<CreateAsync>d__18.MoveNext() + 0x2ad
--- End of stack trace from previous location ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b
   at PuppeteerSharp.Launcher.<LaunchAsync>d__8.MoveNext() + 0x786
   --- End of inner exception stack trace ---
   at PuppeteerSharp.Launcher.<LaunchAsync>d__8.MoveNext() + 0x979
--- End of stack trace from previous location ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20
   at PuppeteerSharp.Launcher.<LaunchAsync>d__8.MoveNext() + 0x248
--- End of stack trace from previous location ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b
   at Program.<<Main>$>d__0.MoveNext() + 0x11f
--- End of stack trace from previous location ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b
   at Program.<Main>(String[] args) + 0x24
   at PuppeteerSharpRepro!<BaseAddress>+0x57ebb3

Versions

  • Which version of PuppeteerSharp are you using?
    19.0.0

  • Which .NET runtime and version are you targeting? E.g. .NET framework 4.6.1 or .NET Core 2.0.
    .NET 8.0.8

Additional Information

This only happens with the published native AOT build.
Cannot be reproduced with dotnet run.

Checking!

v19.0.1 shipped. Let me know how it goes.

Amazing! Native AOT works now!
@kblok Thank you so much for the free work with such quick turnaround!

Awesome!