Fix SANE environment vars

This commit is contained in:
Ben Olden-Cooligan 2022-10-22 17:29:04 -07:00
parent 6dc5426fdd
commit 83dd49c4ae
8 changed files with 42 additions and 4 deletions

View File

@ -25,7 +25,7 @@
<Import Project="..\NAPS2.Setup\SdkUsers.targets" />
<ItemGroup>
<PackageReference Include="NAPS2.Sane.Binaries" Version="1.0.0" />
<PackageReference Include="NAPS2.Sane.Binaries" Version="1.0.4" />
<PackageReference Include="NAPS2.Tesseract.Binaries" Version="1.0.2" />
<ProjectReference Include="..\NAPS2.Lib.Mac\NAPS2.Lib.Mac.csproj" />

View File

@ -13,7 +13,7 @@
<ItemGroup>
<ProjectReference Include="..\NAPS2.Sdk.Tests\NAPS2.Sdk.Tests.csproj" />
<PackageReference Include="NAPS2.Sane.Binaries" Version="1.0.0" />
<PackageReference Include="NAPS2.Sane.Binaries" Version="1.0.4" />
<PackageReference Include="NAPS2.Wia" Version="1.0.1" />
<PackageReference Include="Moq" Version="4.18.1" />
<PackageReference Include="xunit" Version="2.4.1" />

View File

@ -37,4 +37,6 @@ public interface ISystemCompat
IDisposable? FileReadLock(string path);
IDisposable? FileWriteLock(string path);
void SetEnv(string name, string value);
}

View File

@ -39,6 +39,8 @@ public class LinuxSystemCompat : ISystemCompat
public string GetLoadError() => LinuxInterop.dlerror();
public void SetEnv(string name, string value) => throw new NotSupportedException();
public IDisposable FileReadLock(string path) => new FileStream(path, FileMode.Open, FileAccess.Read);
public IDisposable FileWriteLock(string path) => new FileStream(path, FileMode.Open, FileAccess.Write);

View File

@ -12,4 +12,7 @@ public static class MacInterop
[DllImport("libSystem.dylib")]
public static extern IntPtr dlsym(IntPtr handle, string symbol);
[DllImport("libSystem.dylib")]
public static extern int setenv(string name, string value, int overwrite);
}

View File

@ -43,9 +43,9 @@ public class MacSystemCompat : ISystemCompat
public string PdfiumLibraryName => "libpdfium.dylib";
public string[] SaneLibraryDeps => new[] { "libusb.dylib", "libjpeg.dylib" };
public string[] SaneLibraryDeps => new[] { "libusb-1.0.0.dylib", "libjpeg.62.dylib" };
public string SaneLibraryName => "libsane.dylib";
public string SaneLibraryName => "libsane.1.dylib";
public IntPtr LoadLibrary(string path) => MacInterop.dlopen(path, RTLD_LAZY | RTLD_GLOBAL);
@ -53,6 +53,8 @@ public class MacSystemCompat : ISystemCompat
public string GetLoadError() => MacInterop.dlerror();
public void SetEnv(string name, string value) => MacInterop.setenv(name, value, 1);
public IDisposable FileReadLock(string path) => new FileStream(path, FileMode.Open, FileAccess.Read);
public IDisposable FileWriteLock(string path) => new FileStream(path, FileMode.Open, FileAccess.Write);

View File

@ -38,6 +38,8 @@ public abstract class WindowsSystemCompat : ISystemCompat
public abstract IntPtr LoadSymbol(IntPtr libraryHandle, string symbol);
public void SetEnv(string name, string value) => throw new NotSupportedException();
public IDisposable? FileReadLock(string path) => null;
public IDisposable? FileWriteLock(string path) => null;

View File

@ -10,6 +10,21 @@ public class SaneNativeLibrary : Unmanaged.NativeLibrary
var libraryPath = FindPath(PlatformCompat.System.SaneLibraryName, testRoot);
var libraryDeps = PlatformCompat.System.SaneLibraryDeps
?.Select(path => FindPath(path, testRoot)).ToArray();
if (libraryDeps != null)
{
// If we're using a bundled SANE, we will need to manually set the environment
// variables to the appropriate folders.
var backendsFolder = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(libraryPath)!, "sane"));
var configFolder =
Path.GetFullPath(Path.Combine(Path.GetDirectoryName(libraryPath)!, "..", "_config", "sane"));
// We can't use Environment.SetEnvironmentVariable as that will just change the .NET
// env and won't be visible to SANE. Instead we use setenv which is technically not
// thread-safe but in practice should be fine here.
PlatformCompat.System.SetEnv("LD_LIBRARY_PATH", backendsFolder);
PlatformCompat.System.SetEnv("SANE_CONFIG_DIR", configFolder);
// Note: We can add SANE debug variables here
// PlatformCompat.System.SetEnv("SANE_DEBUG_DLL", "255");
}
var nativeLib = new SaneNativeLibrary(libraryPath, libraryDeps);
return nativeLib;
});
@ -22,16 +37,26 @@ public class SaneNativeLibrary : Unmanaged.NativeLibrary
}
public delegate SaneStatus sane_init_delegate(out int version_code, IntPtr authorize);
public delegate void sane_exit_delegate();
public delegate SaneStatus sane_get_devices_delegate(out IntPtr device_list, int local_only);
public delegate SaneStatus sane_open_delegate(string name, out IntPtr handle);
public delegate void sane_close_delegate(IntPtr handle);
public delegate IntPtr sane_get_option_descriptor_delegate(IntPtr handle, int n);
public delegate SaneStatus sane_control_option_delegate(IntPtr handle, int n, SaneOptionAction a, IntPtr v,
out SaneOptionSetInfo i);
public delegate SaneStatus sane_get_parameters_delegate(IntPtr handle, out SaneReadParameters p);
public delegate SaneStatus sane_start_delegate(IntPtr handle);
public delegate SaneStatus sane_read_delegate(IntPtr handle, byte[] buf, int maxlen, out int len);
public delegate void sane_cancel_delegate(IntPtr handle);
public sane_init_delegate sane_init => Load<sane_init_delegate>();
@ -39,8 +64,10 @@ public class SaneNativeLibrary : Unmanaged.NativeLibrary
public sane_get_devices_delegate sane_get_devices => Load<sane_get_devices_delegate>();
public sane_open_delegate sane_open => Load<sane_open_delegate>();
public sane_close_delegate sane_close => Load<sane_close_delegate>();
public sane_get_option_descriptor_delegate sane_get_option_descriptor =>
Load<sane_get_option_descriptor_delegate>();
public sane_control_option_delegate sane_control_option => Load<sane_control_option_delegate>();
public sane_get_parameters_delegate sane_get_parameters => Load<sane_get_parameters_delegate>();
public sane_start_delegate sane_start => Load<sane_start_delegate>();