Skip to content

Commit 96bf5ad

Browse files
committed
fix: PDFium lookup finds the DLL in its actual bundled location
Windows user report from v0.3.x: "Error loading file: Failed to locate Pdfium library. Tried: .../resources/pdfium.dll ... LoadLibraryError (OS error 126)". The DLL IS in the installer, just not where the runtime was looking. Root cause: tauri.windows.conf.json declares resources as the array form `["pdfium/pdfium.dll"]`, which preserves the relative path — the DLL gets bundled at `<resource_dir>/pdfium/pdfium.dll`. But pdfium_candidate_paths() in fs.rs only probed `<resource_dir>/pdfium.dll` (no subdir), so the file was present but invisible to the loader. Fix: probe both the `pdfium/` subdir and the root in resource_dir AND in every exe-relative fallback location, for all three platforms. The subdir form is listed first since that matches the current bundle config; root forms stay as belt-and-suspenders in case a future config flattens them. macOS was unaffected because tauri.macos.conf.json uses `bundle.macOS.frameworks` which places the dylib in Contents/Frameworks/ directly (already covered by an exe-relative probe). Linux had the same subdir gap as Windows and is also covered.
1 parent 9771021 commit 96bf5ad

1 file changed

Lines changed: 37 additions & 26 deletions

File tree

  • src-tauri/src/commands

src-tauri/src/commands/fs.rs

Lines changed: 37 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -165,36 +165,37 @@ fn pdfium_candidate_paths() -> Vec<String> {
165165
}
166166

167167
// Tauri-resolved resource directory (set during setup()).
168+
//
169+
// Tauri's `bundle.resources` array form preserves relative paths,
170+
// so `"pdfium/pdfium.dll"` in tauri.<target>.conf.json lands at
171+
// `<resource_dir>/pdfium/pdfium.dll` — NOT at the root. Older
172+
// versions of this function only probed the root, which made
173+
// Windows installs fail with "Failed to locate Pdfium library"
174+
// (OS error 126) even though the DLL was in the installer.
175+
// We now probe both the `pdfium/` subdir (where the current
176+
// bundle config actually puts it) and the root (in case a future
177+
// config change flattens it).
168178
if let Some(resource_dir) = RESOURCE_DIR_HINT.get() {
179+
let push = |v: &mut Vec<String>, p: std::path::PathBuf| {
180+
v.push(p.to_string_lossy().into_owned());
181+
};
169182
#[cfg(target_os = "macos")]
170-
v.push(
171-
resource_dir
172-
.join("libpdfium.dylib")
173-
.to_string_lossy()
174-
.into_owned(),
175-
);
183+
{
184+
push(&mut v, resource_dir.join("pdfium").join("libpdfium.dylib"));
185+
push(&mut v, resource_dir.join("libpdfium.dylib"));
186+
}
176187
#[cfg(target_os = "windows")]
177188
{
178-
v.push(
179-
resource_dir
180-
.join("pdfium.dll")
181-
.to_string_lossy()
182-
.into_owned(),
183-
);
184-
v.push(
185-
resource_dir
186-
.join("libpdfium.dll")
187-
.to_string_lossy()
188-
.into_owned(),
189-
);
189+
push(&mut v, resource_dir.join("pdfium").join("pdfium.dll"));
190+
push(&mut v, resource_dir.join("pdfium").join("libpdfium.dll"));
191+
push(&mut v, resource_dir.join("pdfium.dll"));
192+
push(&mut v, resource_dir.join("libpdfium.dll"));
190193
}
191194
#[cfg(target_os = "linux")]
192-
v.push(
193-
resource_dir
194-
.join("libpdfium.so")
195-
.to_string_lossy()
196-
.into_owned(),
197-
);
195+
{
196+
push(&mut v, resource_dir.join("pdfium").join("libpdfium.so"));
197+
push(&mut v, resource_dir.join("libpdfium.so"));
198+
}
198199
}
199200

200201
if let Ok(exe) = std::env::current_exe() {
@@ -207,26 +208,36 @@ fn pdfium_candidate_paths() -> Vec<String> {
207208
{
208209
// Tauri .app bundle layout:
209210
// Contents/MacOS/<binary>
210-
// Contents/Frameworks/libpdfium.dylib ← preferred
211+
// Contents/Frameworks/libpdfium.dylib ← preferred (macOS config uses bundle.macOS.frameworks)
211212
// Contents/Resources/libpdfium.dylib ← fallback
213+
// Contents/Resources/pdfium/libpdfium.dylib ← if array-form resources ever used on macOS
212214
push(&mut v, exe_dir.join("../Frameworks/libpdfium.dylib"));
215+
push(&mut v, exe_dir.join("../Resources/pdfium/libpdfium.dylib"));
213216
push(&mut v, exe_dir.join("../Resources/libpdfium.dylib"));
214217
push(&mut v, exe_dir.join("libpdfium.dylib"));
215218
}
216219

217220
#[cfg(target_os = "windows")]
218221
{
219222
// bblanchon/pdfium-binaries ships the Windows DLL as
220-
// `pdfium.dll` (no `lib` prefix). Try both.
223+
// `pdfium.dll` (no `lib` prefix). Probe flat and
224+
// `pdfium/` subdir forms at both exe root and the
225+
// classic Tauri `resources/` sibling — covers every
226+
// layout variant we've observed across NSIS / MSI /
227+
// portable builds.
221228
push(&mut v, exe_dir.join("pdfium.dll"));
229+
push(&mut v, exe_dir.join("pdfium").join("pdfium.dll"));
222230
push(&mut v, exe_dir.join("libpdfium.dll"));
223231
push(&mut v, exe_dir.join("resources").join("pdfium.dll"));
232+
push(&mut v, exe_dir.join("resources").join("pdfium").join("pdfium.dll"));
224233
}
225234

226235
#[cfg(target_os = "linux")]
227236
{
228237
push(&mut v, exe_dir.join("libpdfium.so"));
238+
push(&mut v, exe_dir.join("pdfium").join("libpdfium.so"));
229239
push(&mut v, exe_dir.join("resources").join("libpdfium.so"));
240+
push(&mut v, exe_dir.join("resources").join("pdfium").join("libpdfium.so"));
230241
push(&mut v, exe_dir.join("../lib/libpdfium.so"));
231242
}
232243
}

0 commit comments

Comments
 (0)