电子应用程序无法仅访问一个网络驱动器上的文件

Electron app can't access files on only one network drive

我正在构建一个 Electron 应用程序来管理 NAS 上的照片集。该 NAS 有两个逻辑卷,名为“alpha”和“beta”。出于我想了解(并修复!)的原因,我的应用程序在尝试针对 Beta 版文件使用 运行 CLI 工具时会收到 ENOENT 错误,但当它针对 Alpha 版文件时 运行s CLI 工具则不会。此外, 允许对两个卷上的文件执行常规 FS 操作(例如 readdir、stat,甚至重命名)而不会出错。例如:应用程序首先了解测试版中的文件,因为它使用 find 扫描文件系统;扫描成功。

我正在使用 CLI 工具 exiftool 从所有这些文件中提取图像元数据(例如尺寸、捕获设备等)。这是我的应用 运行s 的命令,使用 child_process.spawn:

# as a shell command
exiftool -json -n PATH_TO_FILE
// as a node module usable by Electron
const ChildProcess = require('child_process')

module.exports = async function readExif( PATH_TO_FILE ) {
    if (typeof PATH_TO_FILE !== 'string') throw new TypeError('PATH_TO_FILE must be a string')

    let exifStdout = await new Promise(( resolve, reject ) => {
        let stdout = ''
        let stderr = ''
        const process = ChildProcess.spawn(
            'exiftool',
            ['-json', '-n', PATH_TO_FILE],
            { uid: 501, gid: 20 }
        )

        process.on('error', ( error ) => reject(error)) // couldn't launch the process
        process.stdout.on('data', ( data ) => stdout += data)
        process.stderr.on('data', ( data ) => stderr += data)
        process.on('close', () => stderr ? reject(stderr) : resolve(stdout))
    })

    let exifData = JSON.parse(exifStdout)

    return exifData[0] // exiftool always returns an array; unwrap it so our return mirrors our input
}

如果我 运行 从命令行使用节点,无论目标文件在哪里,它都可以工作。如果 Electron 运行s 它,它将对 alpha 有效但对 beta 无效。如果我 运行 它来自 VS Code 中的集成终端,我拒绝了网络文件夹权限,它可以预见地抛出 alpha 和 beta;无论我使用 node 还是 Electron 都是如此,只要它来自 VS Code。

这是 console.log(error) 当 运行 作为打包的 Electron 应用程序时:

Error: spawn exiftool ENOENT
    at Process.ChildProcess._handle.onexit (internal/child_process.js:264:19)
    at onErrorNT (internal/child_process.js:456:16)
    at processTicksAndRejections (internal/process/task_queues.js:81:21) {
  errno: 'ENOENT',
  code: 'ENOENT',
  syscall: 'spawn exiftool',
  path: 'exiftool',
  spawnargs: [
    '-json',
    '-n',
    '/Volumes/beta/photographs/IMG_9999.jpg'
  ]
}

我通过实验验证的事情:

以上所有让我认为这是一个权限问题,但还有很多其他证据表明权限没问题:

我也尽我所能检查基本文件权限,但我看不出有什么不同。这些卷由用户通过 Finder 安装,将它们放置在 /Volumes/alpha/Volumes/beta。挂载时,ls 显示这两个节点具有相同的权限:

/Volumes $ ls -lht
total 64
drwx------  1 Tom   staff    16K Mar 25 18:46 alpha
drwx------  1 Tom   staff    16K Mar 25 02:00 beta
lrwxr-xr-x  1 root  wheel     1B Dec 31  2019 Macintosh HD -> /

我也亲手检查过个别照片的烫发,但它们的权限是一样的。我已经使用 NAS 管理工具来验证我的用户帐户是否可以不受限制地访问这两个卷;确实如此,否则我的手动实验中的 none 会起作用。

并且,作为最后的努力,我将自己的 uid 和 gid 硬编码到 spawn 调用中,让 Electron 像我一样执行命令,但这也没有效果:我仍然得到 ENOENT 当 Electron 运行s exiftool 对抗任何处于测试阶段的文件时,仅仅是因为该文件处于测试阶段。 beta,再次,我有完全访问权限的网络卷,我已经多次授予该应用程序完全访问权限,该应用程序已经以其他几种方式良好地交互,并且在我认为的任何方面都与 alpha 没有明显不同尽管在两个设备上都有 root,但仍可以检测到。

我什至大喊“是的,那里耳鼻喉科!”在它。我完全没有想法。

为什么这两种情况不同,我该如何解决?或者失败了,我该如何进一步调试它?

非常欢迎任何建议。

我的包版本:

电子运行宁Mac运行宁MacOS11.2.3

NAS 运行在 Linux.

的某种风格上使用 ext4 文件系统

指定有效命令的完整路径:

const process = ChildProcess.spawn(
    '/usr/local/bin/exiftool',
    ['-json', '-n', PATH_TO_FILE]
)

我不知道为什么当目标处于 alpha 阶段时不需要这样做,但事实并非如此。

此版本适用于打包的应用程序。