pvginkel / PdfiumViewer

PDF viewer based on Google's PDFium.
Apache License 2.0
972 stars 418 forks source link

Try load native dlls from Assembly.CodeBase if other attempts failed #133

Closed Snipx closed 7 years ago

Snipx commented 7 years ago

.NET uses shadow copying of assemblies in many cases, which prevents the library from finding the native dlls when only considering Assembly.Location property. Assembly.CodeBase refers to the original location of the assembly and reflects actual information on where the native binaries should be located. This fix should fix problem with using library in environments using shadow copying such as ASP.NET and NUnit tests.

Related to Bug #109

pvginkel commented 7 years ago

Thanks for the pull request. I've merged it as is.

pvginkel commented 7 years ago

I decided to revert this PR and take a different approach. I see a lot of different locations where the pdfium.dll can be stored and I don't think it's good idea to just keep adding permutations.

Instead, I've left the original implementation in tact and added a PdfiumResolver class that can be used as follows:

PdfiumResolver.Resolve += (s, e) => e.PdfiumFileName = @"C:\Full\Path\To\pdfium.dll";

This expects an exact path to pdfium.dll. If you've stored the DLL in an architecture dependent path, you need to resolve this yourself, e.g. like this:

PdfiumResolver.Resolve += (s, e) => e.PdfiumFileName = @"C:\Full\Path\To\" + (sizeof(IntPtr) == 8 ?
 "x64" : "x86") + @"\pdfium.dll";

Make sure you set this event before you touch the PdfiumViewer controls or the PdfDocument class. Once an attempt has been done to resolve the PDFium DLL, it won't try again.

Snipx commented 7 years ago

The pull request was not about dealing with some custom architecture-dependent paths, but about the case when projectA references PdfiumViewer and projectB references projectA. This case was not handled properly. Now after you have reverted the pull request it is possible to deal with the problem by customizing PdfiumResolver.Resolve, but I believe this is not how software should work. Rather, I believe it should cover the case I describe out of the box. But still, it is up to you to decide, of course :)

pvginkel commented 7 years ago

I get that but the reason I didn't include the PR is because to me it feels like I was trying to support everything without really understanding what I was trying to support. What really pushed me towards this approach is that #109 already included two new options; not just one new one.

Really I believe the only option PdfiumViewer should natively support is the one where the library is either in the same folder as the PdfiumViewer DLL, or in an architectural dependant sub directory. All other options I think are specific to a deployment, which is not that easy to predict.

I do hope the generic resolved mechanism allows you to implement your scenario properly.