Разрешить PDFium поддерживать x86 и x64
Я создал приложение WinForms, которое использует PDFium для печати PDF-документов. Я установил PDFium из NuGet, и он создал две подпапки в моем проекте - x86 и x64 - как и ожидалось, каждая с соответствующей версией pdfium.dll внутри. Целевая платформа моего приложения установлена на Любой процессор.
Когда я запускаю приложение в режиме отладки на моей 64-битной машине с Windows 10, оно работает отлично. Однако, когда я выпускаю приложение и устанавливаю его по-настоящему на тот же компьютер, PDFium выдает исключение:
System.BadImageFormatException: была предпринята попытка загрузить программу с неверным форматом. (Исключение из HRESULT: 0x8007000B)
Проведя некоторые исследования, я изменил целевую платформу моего приложения на x86 и удалил подпапку x64 из своего проекта. Приложение теперь отлично работает после выпуска, поэтому проблема решена.
Тем не менее, я хотел бы знать, могу ли я заставить свое приложение работать так, чтобы оно поддерживало как x86, так и x64, используя соответствующую версию PDFium для целевого компьютера. Было бы хорошо, если бы он установил 64-битную версию на машины, которые могут ее поддерживать (а это большинство из них в нашей организации, но я чувствую, что мне нужно перейти на 32-битную версию, если мне нужно выбрать одну или другой, для обеспечения совместимости).
2 ответа
Оказалось, что это не имеет ничего общего с PDFium. В моем сценарии, использованном во время установки выпущенного приложения, обе версии pdfium.dll были настроены на публикацию в корневой папке приложения, а не на подпапки с именами x32 и x64. В результате во время установки dll-версия x32 перезаписывала x64-версию, в результате чего приложение вообще не имело x64-dll.
Я использовал этот подход. Основная идея состоит в том, чтобы определить, работает ли программа в 32 или 64-битных средах. Это делается путем проверки размера указателя. В зависимости от результата этой проверки библиотека pdfium.dll
динамически загружается из x86
или x64
подкаталог пути приложения.
private static bool TryLoadNativeLibrary(string path)
{
if (path == null)
return false;
path = Path.Combine(path, IntPtr.Size == 4 ? "x86" : "x64");
path = Path.Combine(path, "pdfium.dll");
return File.Exists(path) && LoadLibrary(path) != IntPtr.Zero;
}
[DllImport("kernel32", SetLastError = true, CharSet = CharSet.Ansi)]
private static extern IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)] string lpFileName);