nozaki_3
@nozaki_3 (野崎)

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

clipboardが使えない

解決したいこと

electron react boilerplateを使用して、ファイル検索アプリを作成しています。
そこで、electron APIのclipboardを使用すると、エラーが発生している状況です。
原因、解決策等わかる方がいればご教授くださいm(_ _"m)

発生している問題・エラー

Error
Cannot read properties of undefined (reading 'writeText')

Call Stack
 CopyPath
  renderer.dev.js:44431:35
 HTMLUnknownElement.callCallback
  renderer.dev.js:10997:14
 Object.invokeGuardedCallbackDev
  renderer.dev.js:11046:16
 invokeGuardedCallback
  renderer.dev.js:11110:31
 invokeGuardedCallbackAndCatchFirstError
  renderer.dev.js:11124:25
 executeDispatch
  renderer.dev.js:15874:3
 processDispatchQueueItemsInOrder
  renderer.dev.js:15906:7
 processDispatchQueue
  renderer.dev.js:15919:5
 dispatchEventsForPlugins
  renderer.dev.js:15930:3
 undefined
  renderer.dev.js:16121:12

image.png

該当するソースコード

App.tsx

<td>
{/* パスをクリックするとクリップボードにコピー */}
  <span
    className="file-link"
    onClick={CopyPath}
    style={{ color: 'blue', cursor: 'pointer', textDecoration: 'underline'}}>
    {result._path}
  </span>
</td>

{/* パスをクリックするとクリップボードにコピー */}
const CopyPath = () =>{
  window.electron.clipboard.copyPath("path");
  // ツールチップ制御
}

preload.ts

  clipboard:{
    // ファイルパスコピー
    copyPath: (copyPath:string) => {
      clipboard.writeText(copyPath);
    } 
  },

自分で試したこと

  • preload.tsへの import {clipboard } from 'electron'; の追加
  • main.ts内webPreferencesへの contextIsolation:true の追加

別アプローチ

上記の問題の原因はいまだわかっていませんが、ipcMainを使用する方法で実装を行いました。
※もしかしたら、reactのバージョンの問題?
App.tsx

変更なし

preload.ts

  clipboard: {
    // パスをコピー
    copyPath: (path: string) => ipcRenderer.invoke('clipboard:copy', path),
  },

main.ts

// パスをコピー
ipcMain.handle('clipboard:copy', (_event, path: string) => {
  clipboard.writeText(path);
});
0

1Answer

すいません、もう見ていらっしゃるか分かりませんが自分もelectronは気になっているので試してみた結果を一応ご報告致します。初心者です。

Electron 20.0.0 | Electron
https://www.electronjs.org/ja/blog/electron-20-0#省略値の変更-nodeintegration-true-指定が無いレンダラーはデフォルトでサンドボックス化されます

これによるとv20よりsandboxオプションがデフォルトで有効になったため、プリロードスクリプトから利用できるAPIが制限されたというのが動作しない原因の模様です。※sandbox下で利用できる限られたAPIについては以下のページに記述があります。

一つ目のリンク先の説明にある通り、以下のようにnodeIntegration: trueまたはsandbox: falseを追加する事でsandboxが無効になり動作するようになりました。
セキュリティを緩めるのには勿論リスクがあるので、(とにかく早く作りたい && 自分にしか迷惑がかからない) という状況以外ではやるべきではないでしょう。おそらく@nozaki_3さんが「別アプローチ」で書かれているようなメッセージ方式が現在の正攻法なのだと思います。

main.ts
  mainWindow = new BrowserWindow({
    ...
    webPreferences: {
      ...
      nodeIntegration: true,
      //sandbox: false,
      ...
    },
  });
0Like

Your answer might help someone💌