theolivenbaum / electron-sharp

MIT License
23 stars 4 forks source link

HostHook - Electron.HostHook.CallAsync task hangs #5

Closed lofcz closed 1 year ago

lofcz commented 1 year ago

Thanks for forking ElectronNET! I guess this is a pretty early issue to file but I can't seem to get HostHook to work and as it's neither working upstream, I'm posting the problem here.

  1. ElectronHostHook/index.ts
    
    // @ts-ignore
    import * as Electron from "electron";
    import { Connector } from "./connector";

export class HookService extends Connector { // @ts-ignore constructor(socket, public app: Electron.App) { // <-- nit: stock type hint for the "socket" param causes tsc to fail super(socket, app); }

onHostReady(): void {
    this.on("changeWallpaper", async (done) => {
        done("hello world");
    });
}

}

2. `connector.ts` is as generated by `electron-sharp add hosthook`

3. Blazor view:
```cs
@code {

    async Task RunCode()
    {
        BrowserWindow? mainWindow = ElectronSharp.API.Electron.WindowManager.BrowserWindows.First(); // debug observation: mainWindow is not null
        string resultFromTypeScript;

        try
        {
            resultFromTypeScript = await ElectronSharp.API.Electron.HostHook.CallAsync<string>("changeWallpaper"); // <-- the task hangs
        }
        catch (Exception e)
        {
            resultFromTypeScript = e.Message;
        }
    }
}

<button onclick="@RunCode">Test</button>

RunCode runs, mainWindow is not nill. I'm not sure whether changeWallpaper is executed but I suspect it isn't. I'm not familiar with ElectronSharp.API.BridgeConnector implementation (to debug HostHook.Call/CallAsync impl, so this is where my investigation ended.

Steps to Reproduce:

  1. run HostHook demo
  2. observe folder picker never pops up
  3. neither working here https://github.com/mehran-mousavi/Electron.net-.Net-6-Demos (in this fork the folder picker shows up but the task hangs)
lofcz commented 1 year ago

Narrowed the problem: In the reference project, I'm already using ts with module set to es6 and apparently Electron requires at least the entry point to be commonjs. (fixed on my side) Built-in functions ElectronHostHook/api are working fine :/

lofcz commented 1 year ago

So I've got it to work after like 16 hours of headache - and never had a better dopamine rush afterwards.

The thing is that main.js generated by ElectronSharp.CLI swallows connection errors to ElectronHostHook silently (see try-catch above const hostHookScriptFilePath = path.join(__dirname, 'ElectronHostHook', 'index.js');). My tsconfig.json in the root of the project had already ElectronHostHook in exclude paths but electron-sharp generates path ./obj/Host which ofc has it's own tsconfig.json but the root one with module set to es6 had priority and kept overwriting transpiled code to es6 which is incompatible with electron (commonjs expected).

For future readers:

  1. your root tsconfig.json - "exclude": ["ElectronHostHook", "obj/Host"]
  2. if that is not enough edit obj/Host/main.js and debug code around ln 410 (after socket.on('console-stderr', (data) => {), try removing try-catch or just throw to see whether the code executes.
  3. if you get errors like can't import { Connector } ... see your transpiled index.js, connector.js in /obj/Host and make sure it's commonjs
  4. default transpiler target is es2015, feel free to push that up at least to 2017
lofcz commented 1 year ago

https://user-images.githubusercontent.com/10260230/211433409-feb3092c-0828-4ece-8771-a54ef355e354.mp4

electron-sharp + some node-gyp magic