如果一个文件当前通过本地应用程序(.pdf -> pdf阅读器)打开,我该如何追踪它的打开状态?
我正在使用electron.js创建一个文件同步应用程序。因此,如果用户想要删除一个文件,我想检查它是否已经被打开。如果已经打开,我想显示一个警告。
文件仍然处于打开状态,请先关闭它。
目前,以下代码片段对我有效(在macOS上测试过)-
在主进程中 -
import util from 'util'
const exec = util.promisify(require('child_process').exec)
const checkFileIsOpen = async (fileName: string): Promise<boolean> => {
try {
const filePath = myAppDocsPath + '/' + fileName.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&')
const { stdout } = await exec('lsof ' + filePath)
console.log('stdout:', stdout)
if (stdout.length === 0) {
// Not in use | File is not open
return false
} else {
// In use | File is open
return true
}
} catch (error) {
console.log('Check file is open error:\n', error)
return false
}
}
使用spawn函数,您将收到对子进程的引用,可以在其上监听exit
事件。以下是一个简单的示例:
const {spawn} = require('child_process');
const PDF_BIN = '/path/to/pdf-viewer';
const fileTracker = {};
const openFile = (fileName) => {
if(fileTracker[fileName])
throw new Error(`${fileName} already open`);
let args = ['-foo','--b','ar',fileName];
let cp = spawn(PDF_BIN, args);
fileTracker[fileName] = cp;
cp.once('error',(err) => {
console.error(err);
console.log(`Error opening ${fileName}`);
delete(fileTracker[fileName]);
});
cp.once('exit',(code,signal) => {
if(signal)
code = signal;
if(code != 0)
console.error(`Recieved exit code ${code} on file ${fileName}`);
delete(fileTracker[fileName]);
})
}
bin
二进制文件在哪里。 - Debotos Das在一个包的帮助下(https://github.com/ronomon/opened),我找到了一个更好的解决方案 -
const checkFileIsOpen = async (fileName: string): Promise<boolean> => {
try {
// myAppDocsPath is a variable of my application specific path
const filePath = myAppDocsPath + '/' + fileName
const paths = [filePath]
return new Promise((resolve, reject) => {
Opened.files(paths, function (error: any, hashTable: Record<string, boolean>) {
console.log(hashTable)
if (error) throw reject(false)
resolve(hashTable[paths[0]])
})
})
} catch (error) {
console.log('Check file is open error:\n', error)
return false
}
}
获取文件列表 -
type FileListOpenStatus = Record<string, boolean> | false
const checkFileListOpenStatus = async (fileNameList: string[]): Promise<FileListOpenStatus> => {
try {
// myAppDocsPath is a variable of my application specific path
const paths = fileNameList.map((fileName) => `${myAppDocsPath}/${fileName}`)
return new Promise((resolve, reject) => {
Opened.files(paths, function (error: any, hashTable: Record<string, boolean>) {
console.log(hashTable)
if (error) throw reject(false)
const results: Record<string, boolean> = {}
for (const [filePath, value] of Object.entries(hashTable)) {
const fileName = path.basename(filePath)
results[fileName] = value
}
resolve(results)
})
})
} catch (error) {
console.log('Check file list open status error:\n', error)
return false
}
}
shell.openPath
打开文件。它没有关闭事件。 - Debotos Das