Electron實現(xiàn)文件復制到剪切板的方案
前言
electron的剪切板沒有提供文件、音頻、視頻等等類型的支持。
技術調研
我們在mac、windows系統(tǒng)中,右鍵本地文件是支持復制的,并寫入到剪切板的速度很快。
基于這個方向,我們查找到了如下方法:
window:使用powershell腳本命令,可以實現(xiàn)文件復制
`powershell -command "& {Set-Clipboard -Path '${filePath}'}"`
mac:使用osascript腳本指令,可以實現(xiàn)文件復制
`osascript -e 'set the clipboard to POSIX file "${filePath}"'`
注意點
powershell和asascript在兩個平臺支持復制文件、音頻、視頻等等,前提條件都是需要文件已經存在于本地。
所以,我們復制的內容必須先現(xiàn)在到本地,再進行復制到剪切板。
實現(xiàn)方案
渲染層提供preload
contextBridge.exposeInMainWorld("mainWindowAPI", {
copyFile: (filePath:string) => ipcRenderer.invoke('copy-file', filePath)
});
復制的實際,需要傳遞已經緩存到本地的文件路徑;
主進程接收ipc
// 復制文件到剪切板
ipcMain.on("copy-file", (event: Electron.IpcMainEvent, filePath: string) => {
// 檢查filePath是否存在,不存在則退出
if(!filePath) {
event.reply("copy-file", false);
return;
}
// 處理base64
if (filePath.startsWith('data:')) {
try {
const image = Buffer.isBuffer(filePath) ? nativeImage.createFromBuffer(filePath) : nativeImage.createFromDataURL(url);
clipboard.writeImage(image)
Logger.log(`【copy-file】復制base64成功`)
event.reply("copy-file", true);
} catch (error) {
Logger.log(`【copy-file】復制base64失敗 ${error}`)
event.reply("copy-file", false);
}
return
}
// 檢查是否為本地路徑,如果不是本地路徑則退出
if(filePath.includes('file://')) {
event.reply("copy-file", false);
return;
}
// 執(zhí)行復制操作
copyFile(filePath.replace("file:///", "")).then((res: boolean) => {
event.reply("copy-file", res);
}).catch(() => {
event.reply("copy-file", false);
})
});
1.檢查filePath是否存在,不存在則退出
2.如果是base64圖片,則使用electron的nativeImage轉換成為PNG圖片(或者jpg等,可以看官網(wǎng))
3.檢查是否為本地路徑,如果不是本地路徑則退出,因為復制到剪切板必須是本地文件,網(wǎng)絡連接是不支持的
4.是本地連接,去除file:///頭,只需要后面的文件路徑,路徑如下:/Users/自己設備的賬戶名/Library/Application Support/應用名稱/Cache/test.dmg
檢查不同平臺
/**
* 復制文件到剪貼板
*
* @param localFileUrl 本地文件URL
* @returns 復制結果,成功為true,失敗為false
*/
export function copyFile(localFileUrl: string) {
if (process.platform === 'darwin') {
return copyFileForMac(localFileUrl);
} else if (process.platform === 'win32') {
return copyFileForWindows(localFileUrl)
}
}
mac系統(tǒng)復制到剪切板
/**
* 將文件復制到Mac的剪貼板
*
* @param localFileUrl 本地文件的URL路徑
* @returns 返回一個Promise,成功時返回true,失敗時返回錯誤消息
*/
function copyFileForMac(localFileUrl: string) {
return new Promise((resolve, reject) => {
// 文件的路徑
const filePath = path.resolve(localFileUrl);
Logger.log(`【copyFileForMac】Copying file to clipboard: ${filePath}`)
// 使用AppleScript將文件復制到剪貼板
const copyFileToClipboardScript = `osascript -e 'set the clipboard to POSIX file "${filePath}"'`;
// 執(zhí)行AppleScript
try {
// 檢查文件是否存在本地
if (!fs.existsSync(filePath)) {
reject(false)
Logger.error(`【copyFileForMac】Error: File not found at path ${filePath}`);
}
exec(copyFileToClipboardScript, (error: { message: any; }, stdout: any, stderr: any) => {
if (error) {
reject(false)
Logger.error(`【copyFileForMac】Error: ${error.message}`);
return;
}
if (stderr) {
reject(false)
Logger.error(`【copyFileForMac】Error: ${stderr}`);
return;
}
resolve(true)
Logger.log('【copyFileForMac】文件已經被寫入剪切板');
});
} catch (error) {
Logger.error(`【copyFileForMac】Error: ${error}`);
reject(false)
}
});
}
windows系統(tǒng)復制到剪切板
/**
* 將文件復制到Windows系統(tǒng)的剪貼板
*
* @param localFileUrl 文件路徑
* @returns 返回一個Promise,如果成功復制到剪貼板,則resolve為true;如果失敗,則reject為錯誤信息
*/
function copyFileForWindows(localFileUrl: string) {
return new Promise((resolve, reject) => {
// 文件的路徑
const filePath = path.resolve(localFileUrl);
Logger.log(`【copyFileForWindows】Copying file to clipboard: ${filePath}`)
// 使用powershell命令將文件復制到剪貼板
const copyFileToClipboardScript = `${powershellBin} -command "& {Set-Clipboard -Path '${filePath}'}"`;
// 執(zhí)行powershell命令
try {
// 檢查文件是否存在本地
if (!fs.existsSync(filePath)) {
reject(false)
Logger.error(`【copyFileForMac】Error: File not found at path ${filePath}`);
}
exec(copyFileToClipboardScript, (error: { message: any; }, stdout: any, stderr: any) => {
if (error) {
reject(error)
Logger.error(`【copyFileForWindows】Error: ${error.message}`);
return;
}
if (stderr) {
reject(stderr)
Logger.error(`【copyFileForWindows】Error: ${stderr}`);
return;
}
resolve(true)
Logger.log('【copyFileForWindows】文件已經被寫入剪切板');
});
} catch (error) {
reject(error)
Logger.error(`【copyFileForWindows】Error: ${error}`);
}
});
}
總結
electron的clipboard剪切板只支持text、html、rtf、bookmark、writeImage等,5種類型寫入到剪切板,并不支持其他文件類型、如file、video、audio等等
const { clipboard } = require('electron')
clipboard.write({
text: 'test',
html: '<b>Hi</b>',
rtf: '{\rtf1\utf8 text}',
bookmark: 'a title'
})
console.log(clipboard.readText())
// 'test'
console.log(clipboard.readHTML())
// <meta charset='utf-8'><b>Hi</b>
console.log(clipboard.readRTF())
// '{\rtf1\utf8 text}'
console.log(clipboard.readBookmark())
// { title: 'a title', url: 'test' }
我們參考系統(tǒng)級別的復制體性,最終實現(xiàn)了的文件復制到剪切板功能。
能夠實現(xiàn)的前提是,文件已經存儲在用戶本地設備。
補充
業(yè)務層面,如何將文件緩存到本地,則需要用到electron的WebRequest網(wǎng)絡攔截功能,再業(yè)務層資源下拉的時候攔截對應的請求,并將資源緩存到我們指定的文件夾位置,后續(xù)復制的時候,則直接讀取緩存的文件路徑提供給 copy-file。
以上就是Electron實現(xiàn)文件復制到剪切板的方案的詳細內容,更多關于Electron文件復制到剪切板的資料請關注腳本之家其它相關文章!
相關文章
JavaScript實現(xiàn)表格表單的隨機選擇和簡單的隨機點名
本文主要介紹了JavaScript實現(xiàn)表格表單的隨機選擇和簡單的隨機點名,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-08-08
js判斷是否為數(shù)組的函數(shù): isArray()
像 Ajaxian,StackOverflow 等,搜一下,到處都在討論 isArray() 的實現(xiàn)。對于一切都是對象的 JavaScript 來說,確實有點麻煩2011-10-10
使用javascript實現(xiàn)Iframe自適應高度
這篇文章主要介紹了使用javascript實現(xiàn)Iframe自適應高度,需要的朋友可以參考下2014-12-12
JavaScript navigator.userAgent獲取瀏覽器信息案例講解
這篇文章主要介紹了JavaScript navigator.userAgent獲取瀏覽器信息案例講解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下2021-08-08
探析瀏覽器執(zhí)行JavaScript腳本加載與代碼執(zhí)行順序
本文主要基于向HTML頁面引入JavaScript的幾種方式,分析HTML中JavaScript腳本的執(zhí)行順序問題,通過本文給大家分享瀏覽器執(zhí)行JavaScript腳本加載與代碼執(zhí)行順序,對瀏覽器執(zhí)行javascript及執(zhí)行順序相關知識感興趣的朋友一起學習吧2016-01-01

