Tengo una aplicación de administrador de archivos Electron, que crea 2 ventanas para diferentes propósitos:
quickView una ventana de representación utilizada para obtener una vista previa de los archivos locales. Utiliza el oyente "will-download" para detectar archivos no compatibles al evitar la descarga.
main la ventana principal del renderizador. Utiliza el oyente "will-download" para descargar archivos.
Cada uno con sus propios oyentes will-download adjuntos a su sesión. Pero por alguna razón, el oyente quickView sobrescribe al oyente main .
En la siguiente línea, estoy creando un oyente de will-download para el proceso "principal". El propósito de este oyente es descargar archivos:
win.webContents.session.on('will-download', listener) El parámetro windows.main en la línea de abajo es la referencia win en la línea de arriba:
const resultInfo = await downloadManager.download(windows.main, { En la siguiente línea, estoy creando un oyente de will-download para la ventana "QuickView". El propósito de este agente de escucha es detectar archivos no admitidos (lo que activa el evento de descarga en Chromium) y evitar el evento de descarga:
windows.quickViewWindow.webContents.session.once('will-download', _willDownloadHandler) No he encontrado otra forma de detectar archivos no admitidos, por lo que estoy usando un evento will-download en primer lugar.
Por alguna razón, el controlador de will-download de la ventana quickView anula el controlador de main :
Cuando activo el evento de descarga de la actualización de la aplicación aquí (desde el proceso main ):
const resultInfo = await downloadManager.download(windows.main, { Activa el controlador de eventos de la ventana del renderizador quickView :
function _willDownloadHandler (event, item, webContents) { ... windows.main.webContents.send('load:webview::failed', {path: fileURL}) Solucioné parcialmente el problema en este compromiso especificando un nombre de partición personalizado para la sesión de la ventana de quickView , por lo que no usa la sesión predeterminada y no sobrescribe el oyente will-download creado por main :
windows.quickViewWindow = new electron.BrowserWindow({ ... webPreferences: { partition: 'quickPreview', ... windows.quickViewWindow.webContents.session.once( 'will-download', (event, item, webContents) => { event.preventDefault() ... } ) ipcRenderer.on('load:webview', (event, data) => { ... webviewNode.setAttribute('partition', 'quickPreview')Pero esta solución resultó en otro problema:
La ventana de vista rápida dejó de funcionar en la compilación de producción (tal vez tenga algo que ver con el protocolo que no funciona con la partición de sesión no predeterminada)
Establecer una partición personalizada en una vista web hace que la asociación del enlace del protocolo de Windows aparezca en producción cuando se crea la ventana que contiene esta vista web:

Creo que podría deberse al protocolo app:// personalizado creado por el complemento electron-builder . Parece que la ventana emergente se activa con el enlace "aplicación".
O tal vez está sucediendo porque estoy configurando el protocolo incorrectamente cuando estoy creando la ventana en algún lugar alrededor de esta línea:
git clone https://github.com/aleksey-hoffman/sigma-file-manager.git cd sigma-file-manager npm install git checkout 47ce65b npm run electron:build./dist_electronAcabo de revertir el compromiso 47ce65b y agregué algunos valores de prueba para que sea más fácil depurar
Para cambiar a la última confirmación y crear la compilación de producción:
git checkout 5246252 npm run electron:build Todo el console.log() dentro electronMain.js se muestra en la ventana del terminal (línea de comando) (no en la consola de herramientas del desarrollador).
Para activar la función de vista rápida:
Para activar un evento de descarga, simplemente abra la página "Navegador" y arrastre y suelte cualquier archivo (o URL del sitio web) desde Internet. Activará el controlador de eventos de descarga incorrecta (el controlador de la ventana QuickView), y debería ver el mensaje de la consola.
La ventana de vista rápida que contiene esta vista web se crea en el evento app.ready . Cuando se especifica la partición, la ventana emergente aparecerá justo después de que se cree la ventana QuickView:
Pude reproducirlo con este código:
let window1 = null let window2 = null electron.app.on('ready', async () => { createWindow1() createWindow2() setTimeout(() => { console.log('trigger window 1 download') window1.webContents.downloadURL('https://stackoverflow.com') }, 1000) }) function createWindow2 () { window1.webContents.session.once('will-download', downloadHandler1) window2.webContents.session.once('will-download', downloadHandler2) } function createWindow1 () { window1 = new electron.BrowserWindow() window1.loadURL('app://./quickViewWindow.html') window1.webContents.session.once('will-download', downloadHandler1) } function createWindow2 () { window2 = new electron.BrowserWindow() window2.loadURL('app://./quickViewWindow.html') window2.webContents.session.once('will-download', downloadHandler2) } function downloadHandler1 (event, item, webContents) { console.log('window will-download handler 1') } function downloadHandler2 (event, item, webContents) { console.log('window will-download handler 2') } Cuando se ejecuta setTimeout , veo los siguientes mensajes de console.log() :
trigger window 1 download window will-download handler 1 window will-download handler 2Como puede ver en el registro, el evento de descarga activa los controladores de eventos de ambas ventanas
Si especifico una partición separada para cada ventana, el problema con los controladores de eventos compartidos se resuelve, pero aparece el segundo problema mencionado anteriormente: la asociación de enlaces aparece al iniciar
window1 = new electron.BrowserWindow({ webPreferences: { partition: 'partition1', } }) window2 = new electron.BrowserWindow({ webPreferences: { partition: 'partition2', } })Me lo imaginé. Si esa es una forma incorrecta de hacerlo, por favor alguien hágamelo saber.
Así es como lo arreglé:
Establezca un nombre de partición personalizado para la ventana, de modo que use su propio webContents.session en lugar de compartir el predeterminado.
windows.quickViewWindow = new electron.BrowserWindow({ ... webPreferences: { partition: 'quickView', ... windows.quickViewWindow.webContents.session.once( 'will-download', (event, item, webContents) => { event.preventDefault() ... } ) ipcRenderer.on('load:webview', (event, data) => { ... webviewNode.setAttribute('partition', 'quickView') Establezca el protocolo file:// en la ruta de producción para la URL de la ventana:
productionPath = `file://${__static}/quickViewWindow.html`Aquí está la confirmación: https://github.com/aleksey-hoffman/sigma-file-manager/commit/31208809cda7614a7c2f32237ae14f6c9c602f8f