HostHook event isn't being called #543

Closed
opened 2026-01-29 16:42:33 +00:00 by claunia · 2 comments
Owner

Originally created by @danatcofo on GitHub (Aug 3, 2020).

Originally assigned to: @GregorBiswanger on GitHub.

  • API: 9.31.2

  • CLI: 9.31.2

  • Windows: NETCORE3.1

Steps to Reproduce:

  1. run electronize add hosthook
  2. add this to onHostReady in index.ts
        console.info("HostHook has been initialized");
        this.on("showOpenDialogMain",
            async (options: Electron.OpenDialogOptions) => {
                console.info("showOpenDialogMain has been called");
                const showOpenDialogMainResult = await Electron.dialog.showOpenDialog(options);
                return showOpenDialogMainResult.canceled ? [] : showOpenDialogMainResult.filePaths || [];
            });
  1. add this to a tray menu
            new MenuItem
            {
                Type = MenuType.normal,
                Label = "Open a file",
                Click = () =>
                {
                    Task.Run(async () =>
                    {
                        _logger.LogInformation("Calling showOpenDialogMain");
                        var files = await Electron.HostHook.CallAsync<string[]>(
                            "showOpenDialogMain",
                            new OpenDialogOptions
                            {
                                Properties = new[] {OpenDialogProperty.openFile},
                            }).ConfigureAwait(false);
                    }).ConfigureAwait(false);
                }
            };
  1. run the code and select Open a file from the tray menu option.
  2. observe that the Calling showOpenDialogMain and HostHook has been initialized are both in the logs but showOpenDialogMan has been called is never emitted.

Root of this is that I need an open dialog to occur when there is no window actually live. All the dialog options never account for the cases of not having any browser windows actually living. This code is based on the code sample from the repo.

I've attempted this same code with no extra parameters as well to the same result.

Originally created by @danatcofo on GitHub (Aug 3, 2020). Originally assigned to: @GregorBiswanger on GitHub. * **API**: 9.31.2 * **CLI**: 9.31.2 * **Windows**: NETCORE3.1 Steps to Reproduce: 1. run electronize add hosthook 2. add this to onHostReady in index.ts ``` console.info("HostHook has been initialized"); this.on("showOpenDialogMain", async (options: Electron.OpenDialogOptions) => { console.info("showOpenDialogMain has been called"); const showOpenDialogMainResult = await Electron.dialog.showOpenDialog(options); return showOpenDialogMainResult.canceled ? [] : showOpenDialogMainResult.filePaths || []; }); ``` 3. add this to a tray menu ``` new MenuItem { Type = MenuType.normal, Label = "Open a file", Click = () => { Task.Run(async () => { _logger.LogInformation("Calling showOpenDialogMain"); var files = await Electron.HostHook.CallAsync<string[]>( "showOpenDialogMain", new OpenDialogOptions { Properties = new[] {OpenDialogProperty.openFile}, }).ConfigureAwait(false); }).ConfigureAwait(false); } }; ``` 4. run the code and select Open a file from the tray menu option. 5. observe that the `Calling showOpenDialogMain` and `HostHook has been initialized` are both in the logs but `showOpenDialogMan has been called` is never emitted. Root of this is that I need an open dialog to occur when there is no window actually live. All the dialog options never account for the cases of not having any browser windows actually living. This code is based on the code sample from the repo. I've attempted this same code with no extra parameters as well to the same result.
claunia added the bug label 2026-01-29 16:42:34 +00:00
Author
Owner

@GregorBiswanger commented on GitHub (Aug 14, 2020):

Electrons dialog.showOpenDialog function requires a renderer instance (window). There are some bugs in your code.

You need JsonSerializer options from NewtonsoftJson for the OpenDialogOptions.

var menu = new MenuItem
{
    Type = MenuType.normal,
    Label = "Open a file",
    Click = async () =>
    {
            var _jsonSerializer = new JsonSerializer()
            {
                ContractResolver = new CamelCasePropertyNamesContractResolver(),
                NullValueHandling = NullValueHandling.Ignore,
                DefaultValueHandling = DefaultValueHandling.Ignore
            };

            var options = JObject.FromObject(new OpenDialogOptions
            {
                Properties = new[] { OpenDialogProperty.openFile }
            }, _jsonSerializer);

            var files = await Electron.HostHook.CallAsync<string[]>("showOpenDialogMain", options);
            Console.WriteLine(files);
    }
};
Electron.Menu.SetApplicationMenu(new MenuItem[] { menu });

With the HostHook project, you have to send your asynchronous response back via a done callback.

// @ts-ignore
import * as Electron from "electron";
// @ts-ignore
import { dialog, BrowserWindow } from "electron";
import { Connector } from "./connector";

export class HookService extends Connector {
    constructor(socket: SocketIO.Socket, public app: Electron.App) {
        super(socket, app);
    }

    onHostReady(): void {
        console.info("HostHook has been initialized");
        this.on("showOpenDialogMain", async (options: Electron.OpenDialogOptions, done) => {
            console.info("showOpenDialogMain has been called");
            const window = BrowserWindow.getAllWindows()[0];
            const showOpenDialogMainResult = await dialog.showOpenDialog(window, options);
            const result = showOpenDialogMainResult.canceled ? [] : showOpenDialogMainResult.filePaths || [];

            done(result);
        });
    }
}

The code snippets work for me. I hope I have helped you with the informations.

@GregorBiswanger commented on GitHub (Aug 14, 2020): Electrons `dialog.showOpenDialog` function requires a renderer instance (window). There are some bugs in your code. You need JsonSerializer options from NewtonsoftJson for the OpenDialogOptions. ``` var menu = new MenuItem { Type = MenuType.normal, Label = "Open a file", Click = async () => { var _jsonSerializer = new JsonSerializer() { ContractResolver = new CamelCasePropertyNamesContractResolver(), NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore }; var options = JObject.FromObject(new OpenDialogOptions { Properties = new[] { OpenDialogProperty.openFile } }, _jsonSerializer); var files = await Electron.HostHook.CallAsync<string[]>("showOpenDialogMain", options); Console.WriteLine(files); } }; Electron.Menu.SetApplicationMenu(new MenuItem[] { menu }); ``` With the HostHook project, you have to send your asynchronous response back via a done callback. ``` // @ts-ignore import * as Electron from "electron"; // @ts-ignore import { dialog, BrowserWindow } from "electron"; import { Connector } from "./connector"; export class HookService extends Connector { constructor(socket: SocketIO.Socket, public app: Electron.App) { super(socket, app); } onHostReady(): void { console.info("HostHook has been initialized"); this.on("showOpenDialogMain", async (options: Electron.OpenDialogOptions, done) => { console.info("showOpenDialogMain has been called"); const window = BrowserWindow.getAllWindows()[0]; const showOpenDialogMainResult = await dialog.showOpenDialog(window, options); const result = showOpenDialogMainResult.canceled ? [] : showOpenDialogMainResult.filePaths || []; done(result); }); } } ``` The code snippets work for me. I hope I have helped you with the informations.
Author
Owner

@danatcofo commented on GitHub (Aug 14, 2020):

Thanks.. that worked however, I did alter your working example here to function without having windows already created.

        this.on("showOpenDialogMain", async (options: Electron.OpenDialogOptions, done) => {
            console.info("showOpenDialogMain has been called");

            var window = new BrowserWindow({
                frame: false,
                skipTaskbar: true,
                height: 1,
                width: 1,
                x: -99999999,
                y: -99999999
            });

            const showOpenDialogMainResult = await dialog.showOpenDialog(window, options);
            const result = showOpenDialogMainResult.canceled ? [] : showOpenDialogMainResult.filePaths || [];

            window.close();

            done(result);
        });

@danatcofo commented on GitHub (Aug 14, 2020): Thanks.. that worked however, I did alter your working example here to function without having windows already created. ``` this.on("showOpenDialogMain", async (options: Electron.OpenDialogOptions, done) => { console.info("showOpenDialogMain has been called"); var window = new BrowserWindow({ frame: false, skipTaskbar: true, height: 1, width: 1, x: -99999999, y: -99999999 }); const showOpenDialogMainResult = await dialog.showOpenDialog(window, options); const result = showOpenDialogMainResult.canceled ? [] : showOpenDialogMainResult.filePaths || []; window.close(); done(result); }); ```
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/Electron.NET#543