cocos 通過 electron 打包成 exe 文件,實現通信問題
首先,我使用的 cocos 版本是 2.4.12,遇到一個問題,是啥子呢,就是我要把用 cocos 開發出來的項目打包成一個 exe 可執行程序,使用的是 electron ,現在我有一個需求,就是在 cocos 中開發一個“退出”按鈕,點擊這個按鈕的時候,關閉 exe 程序。
cocos關閉exe程序
首先需要明白一個問題,就是 cocos 里面開發的 “退出”按鈕
隸屬于 cocos 項目,與 electron 毫無關系;但是關閉 exe
可執行程序呢,是 electron 的功能,與 cocos 毫無關系;
但是現在我的需求是要把 cocos 和 electron 關聯起來。
所以我的方案是:想辦法,在 cocos 點擊關閉按鈕的時候,由 cocos 向 electron 發送一個消息,當 electron 收到 cocos 傳遞過來的消息的時候,則由 electron 主動關閉 exe 窗口,這樣就實現了點擊按鈕關閉功能。
上面的方案可行嗎?非常可行,親測可行!
方案
我使用的是 Electron 的 IPC (Inter-Process Communication) 機制,也就是 ipcMain
和 ipcRenderer
。
首先在cocos部分,寫一個按鈕,綁定一個點擊事件,這個步驟我就不詳細說了, 主要是這個點擊事件里面是什么,也就是說怎么給 electron 發送消息:
// 關閉應用closeAppFunc() {window.ipcRenderer.send('close-app');}
其實就是上面這段代碼,通過 ipcRenderer
,向 electron 發送一個 close-app
消息,當然 close-app
這個名字是自己起的,你叫啥都可以。
沒了,這就是發送消息,window 是全局的,但是 window 上面其實是沒有 ipcRenderer
的,先別急哈。
然后,就是修改 electron ,讓它接收 cocos 發送過來的 close-app
消息。
首先我們在 electron 項目(electron-quick-start-exe)下面找到 main.js
文件,我們在 createWindow
方法里面,添加下面這段代碼:
ipcMain.on('close-app', () => {mainWindow.close();app.quit()})
這段代碼的意思就是接收到 close-app
消息之后關閉窗體,當然,ipcMain
找不到,我們需在文件開頭引入一下子:
const { ipcMain } = require('electron');
好,這樣 electron 就可以了。
但是,上面在 cocos 里面發送消息的時候說了, window
里面并沒有 ipcRenderer
, 怎么辦呢?沒關系,我們在編譯 cocos 文件之后,生成了一個 web-mobile
文件夾,在里面呢,有一個 index.html
文件,我們編輯這個文件,在他的 body 標簽前面添加下面這段 js 代碼:
<script type="text/javascript" >const { ipcRenderer } = require('electron');window.ipcRenderer = ipcRenderer;
</script>
OK,上面步驟完成之后,就可以打包了,打包完成就好使了!
注意,瀏覽器測試沒用,必須打包成 exe 文件才可以用,瀏覽器測試會報錯!!
electron 向 cocos 傳遞數據
上面說了一個通過 cocos 向 electron 傳遞數據,現在要說一下 electron 向 cocos 傳遞數據,啊哈哈哈哈!
為啥子說這個呢?因為我呢,還有一個需求,就是 打包后的 exe 可執行程序啊,需要讀取當前文件夾下面的一個 json 文件,讀取之后呢,需要在 cocos 程序中使用,你看這事兒鬧的,這他媽的復雜,沒關系,小意思!
方案
首先呢,我是這樣想的,我在 cocos 一加載完啊,就給 electron 發送一個消息,告訴 electron 說,你得給我加載這個 json 文件啦!和上面的通信方式是一樣的哈:
window.ipcRenderer.send('get-config');
你看,就一句代碼,告訴 electron 給我加載文件!
然后 electron 收到 cocos 傳遞的消息之后呢,就可以加載這個 json 文件了,加載完文件之后,通過 reply
在把讀取到的數據返回給 cocos :
ipcMain.on('get-config', (event) => {const p = path.resolve('./')// 讀取當前文件加下 wjw.json 文件const resourcesPath = path.join(p, 'wjw.json');// 開始讀文件fs.readFile(resourcesPath, 'utf8', (err, data) => { if (err) throw err; // 如果報錯就拋出錯誤console.log(data); // 打印一下數據event.reply('wjw-data', data); // 把數據返回給 cocos});})
然后就簡單了,cocos 里面接收一下就可以啦:
window.ipcRenderer.on('wjw-data', (event, data) => {// 把數據放進緩存cc.sys.localStorage.setItem('wjwData', data);// 從緩存里面讀一下let value = cc.sys.localStorage.getItem('wjwData');// 打印一下緩存取出來的數據console.log('wjw-data 緩存讀取的數據:', JSON.parse(value));
});
就這么簡單!完成!
注意:依舊是需要打包測試,瀏覽器測試會報錯哈!!謹記!