hardkoded / puppeteer-sharp

Headless Chrome .NET API
https://www.puppeteersharp.com
MIT License
3.42k stars 446 forks source link

Failed to connect to browser when used in native AOT app #2746

Closed cfbao closed 3 months ago

cfbao commented 3 months ago

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

Additional Information

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

kblok commented 3 months ago

Checking!

kblok commented 3 months ago

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

cfbao commented 3 months ago

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

kblok commented 3 months ago

Awesome!