Я пытаюсь использовать Puppeteersharp для создания PDF-файлов на сервере и отправки их обратно клиенту. Все это работает локально через localhost и IIS Express на ПК с Windows 11.
Однако, когда я развертываю это на виртуальной машине Azure с IIS (64-разрядная версия Windows Server 2019, 8 ГБ ram) процесс завершается сбоем, потому что не удается загрузить Chrome – и я не знаю, что попробовать...
- Я переключился из пути к папке TEMP в каталог inetpub, где все разрешения ДОЛЖНЫ быть правильными.
- Я могу сверлить загрузить .zip по URL-адресу ниже
- Я могу скачать его прямо из Chrome
at PuppeteerSharp.BrowserFetcher.d__39.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at PuppeteerSharp.BrowserFetcher.d__32.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at PuppeteerSharp.BrowserFetcher.d__28.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at App.Application._Core.Chromium.d__13.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at App.Controllers.API.DataApiController.d__1.MoveNext()
Chromium — это класс-оболочка, который я написал для Puppeteersharp...
Вот код:
Контроллер API данных конечная точка:
[HttpPost]
[Route("some-route")]
public async Task GeneratePdf(RequestDto request)
{
var chromium = new Chromium();
await chromium.DownloadChromium();
Stream stream = await chromium.CreateStreamAsync(request.Html);
MemoryStream ms = new MemoryStream();
stream.CopyTo(ms);
var result = new HttpResponseMessage()
{
Content = new ByteArrayContent(ms.ToArray()),
StatusCode = HttpStatusCode.OK
};
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = $"{request.pdfName}.pdf"
};
return ResponseMessage(result);
}
Хром:
///
/// Wrapper around for creating HTML to PDF attachments
///
public Chromium()
{
_Logger = LogManager.GetCurrentClassLogger();
var directory = AppDomain.CurrentDomain.BaseDirectory;
var driveDownloads = Path.Combine(directory, "chromium");
_InstallDirectory = driveDownloads;
_Logger.Info($"chromium class install directory: [{_InstallDirectory}]");
}
///
/// Download chromium to the provided
///
///
public async Task DownloadChromium()
{
SetupChromiumDownloadDirectory(_InstallDirectory);
_BrowserFetcher = new BrowserFetcher(new BrowserFetcherOptions() { Path = _InstallDirectory });
_Logger.Info($"browser cache download directory: [{_BrowserFetcher.CacheDir}]");
// THIS IS WHERE THE ERROR HAPPENS
_InstalledBrowser = await _BrowserFetcher.DownloadAsync();
return true;
}
///
/// Setup a custom download directory for Puppeter chromium. We need to do this because the default
/// download directory CAN cause an exception because of a path too long exception
///
///
///
private bool SetupChromiumDownloadDirectory(string directory)
{
_Logger.Debug($"Settting up chromium directory: [{directory}]");
bool setup = false;
bool exists = Directory.Exists(directory);
var directoryInfo = new DirectoryInfo(directory);
if (!exists)
{
_Logger.Debug($"Directory does not exist, creating it.");
directoryInfo.Create();
}
var rule = new FileSystemAccessRule("Everyone", FileSystemRights.FullControl, InheritanceFlags.None, PropagationFlags.NoPropagateInherit, AccessControlType.Allow);
var security = directoryInfo.GetAccessControl(AccessControlSections.Access);
security.ModifyAccessRule(AccessControlModification.Set, rule, out setup);
_Logger.Debug($"Setting ModifyAccessControl to SET for directory: [{directory}] result: [{setup}]");
if (!setup)
return false;
rule = new FileSystemAccessRule("Everyone", FileSystemRights.FullControl,
InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit,
PropagationFlags.InheritOnly,
AccessControlType.Allow);
security.ModifyAccessRule(AccessControlModification.Add, rule, out setup);
_Logger.Debug($"Setting ModifyAccessControl to ADD for directory: [{directory}] result: [{setup}]");
if (!setup)
return false;
directoryInfo.SetAccessControl(security);
return setup;
}
Журналирование из Chromium:
2024-09-20 14:30:53.8350 INFO chromium class install directory: [C:\inetpub\wwwroot\chromium]
2024-09-20 14:30:53.8506 DEBUG Settting up chromium directory: [C:\inetpub\wwwroot\chromium]
2024-09-20 14:30:53.8506 DEBUG Setting ModifyAccessControl to SET for directory: [C:\inetpub\wwwroot\chromium] result: [True]
2024-09-20 14:30:53.8506 DEBUG Setting ModifyAccessControl to ADD for directory: [C:\inetpub\wwwroot\chromium] result: [True]
2024-09-20 14:30:53.8506 INFO browser cache download directory: [C:\inetpub\wwwroot\chromium]
Подробнее здесь: https://stackoverflow.com/questions/790 ... sync-fails