Closed michaelfoidl closed 5 years ago
@michaelfoidl I can confirm that this package works with Angular 7. It would be great if you could share some of your code to help you.
Since the project I am working on unforntunately is not public, I cannot just share the whole repository. But I'll try my best to sketch the structure.
This is my package.json
-File:
{
"name": "norris",
"version": "1.0.0",
"private": true,
"scripts": {
"angular:build": "ng build",
"angular:serve": "ng serve",
"electron:build": "tsc -p ./src/tsconfig.electron.json",
"electron:serve": "wait-on http-get://localhost:4200/ && npm run electron:build && electron ./dist/electron/main.js --serve",
"start": "npm run angular:build && npm run electron:build && electron ./dist/electron/main.js",
"watch": "npm-run-all --parallel angular:serve electron:serve"
},
"dependencies": {
"@angular/animations": "~7.2.0",
"@angular/cdk": "^7.3.1",
"@angular/common": "~7.2.0",
"@angular/compiler": "~7.2.0",
"@angular/core": "~7.2.0",
"@angular/forms": "~7.2.0",
"@angular/material": "^7.3.1",
"@angular/platform-browser": "~7.2.0",
"@angular/platform-browser-dynamic": "~7.2.0",
"@angular/router": "~7.2.0",
"core-js": "^2.5.4",
"guid-typescript": "^1.0.9",
"jquery": "^3.3.1",
"material-design-icons": "^3.0.1",
"ngx-electron": "^2.1.1",
"rxjs": "~6.3.3",
"tslib": "^1.9.0",
"ytdl-core": "=0.29.0",
"zone.js": "~0.8.26"
},
"devDependencies": {
"@angular-devkit/build-angular": "~0.13.0",
"@angular/cli": "~7.3.1",
"@angular/compiler-cli": "~7.2.0",
"@angular/language-service": "~7.2.0",
"@types/electron": "^1.6.10",
"@types/jquery": "^3.3.29",
"@types/node": "~8.9.4",
"@types/promise.prototype.finally": "^2.0.3",
"codelyzer": "~4.5.0",
"electron": "^4.0.4",
"electron-builder": "^20.38.5",
"npm-run-all": "4.1.5",
"ts-node": "~7.0.0",
"tslint": "~5.11.0",
"typescript": "~3.2.2",
"wait-on": "3.2.0"
}
}
I have not modified the angular.json
file generated by angular-cli
.
This is my tsconfig.json
-File:
{
"compileOnSave": false,
"compilerOptions": {
"baseUrl": "./",
"outDir": "./dist",
"sourceMap": true,
"declaration": false,
"module": "commonjs",
"moduleResolution": "node",
"noImplicitAny": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"importHelpers": true,
"target": "es2018",
"paths": {
"*": [
"node_modules/*",
"src/app/modules/*"
]
},
"typeRoots": [
"node_modules/@types"
],
"lib": [
"es2018",
"dom"
]
}
}
There are two other tsconfig.json
-Files extending this one: One for the electron-Part and one for the angular-Part.
This is the angular-Part:
{
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../dist/app",
"types": [
"node"
]
}
}
This is the electron-Part:
{
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../dist/electron",
"types": []
},
"include": [
"electron/main.ts"
]
}
All the angular-specific code is in src\app
and all the electron-specific code is in src\electron
. I have imported the NgxElectronModule
in my AppModule
and I am getting an instance of Electron-Service via DI in one of my services that is resolved via DI as well. However, for resolving my internal services I use InjectionTokens in order to be more flexible. In the constructor of the service, I try to access ipcRenderer
(isElectronApp
is true), but I always get null:
constructor(
@Inject(ElectronService)
electronService: ElectronService
) {
this.electronService = electronService;
if (this.electronService.isElectronApp) {
console.log(this.electronService.ipcRenderer.sendSync("ping")); // cannot resolve sendSync of null
}
}
I understand that this only works when serving the app inside electron, which I do via npm run watch
- still null.
i have some error but also shell is null i used angular 7.2.2 ionic 4.1.1 capacitor beta-19
@niuwenbo in the attached screenshot I noticed that isElectronApp
variable is false
.
@bampakoa In electron side if we are using webview then we have to enable the nodeintegration and due to that jquery does not work. But if we disable nodeintegration then we are not able to access any electron service in angular.
Below is the code for Electron without nodeintegration:
main.js
`const { app, BrowserWindow, globalShortcut } = require('electron');
let mainWindow;
app.on('ready', () => { mainWindow = new BrowserWindow({ width: 1920, height: 1200, frame: true });
app.on('window-all-closed', function () { app.quit(); })
mainWindow.loadURL('file://' + __dirname + '/index.html'); mainWindow.maximize();
globalShortcut.register('f5', function () { mainWindow.reload(); });
});`
index.html
`
`
in Angular side everything is null:
`if(this._electronService.isElectronApp){
alert('ipc ren '+ this._electronService.ipcRenderer);
alert('webFrame '+ this._electronService.webFrame);
alert('remote '+ this._electronService.remote);
if(this._electronService.remote)
{
alert('ipcMain '+ this._electronService.remote.ipcMain);
}
}`
@akjhacse you do not need to disable nodeIntegration
for jquery to work, if you import it like below:
<!-- Insert this line above script imports -->
<script>if (typeof module === 'object') {window.module = module; module = undefined;}</script>
<!-- normal script imports etc -->
<script src="scripts/jquery.min.js"></script>
<!-- Insert this line after script imports -->
<script>if (window.module) module = window.module;</script>
This maybe the case also for @michaelfoidl
@bampakoa This would not work for me since I do not import third party scripts like JQuery using AngularCLI's the scripts-section, but directly through TypeScript as modules. This means that I cannot influence the order in which the scripts are loaded.
Same issue here
Hello,
I have same issue with a Ionic 4 application, code below
if(this.electron.isElectronApp) {
console.log("im in electron !");
let pong: string = this.electron.ipcRenderer.sendSync('store-data');
console.log(pong);
}
displays "I'm in electron" but then it shows an error "TypeError: Cannot read property 'sendSync' of null"
A question: I had the null
problem, too. Enabling nodeIntegration
makes it work. But I got a security warning in Developer Tools: Electron Security Warning (Insecure Content-Security-Policy)
Is there a way to make ngx-electron work with nodeIntegration:false
?
I thought the whole point of using ngx-electron
was not to enable nodeIntegration
...
I thought the whole point of using
ngx-electron
was not to enablenodeIntegration
...
me too, and it's not even documented (at least haven't seen it). But I prefer event-driven over polling (in case of remote
) - but maybe I'm doing something wrong, that's why I'm asking
Hi everyone,
I got the same error then you guys: (the 'true' value is from console.log(this._electronService.isElectronApp);) I'm working on Angular 7 and Electron 5.
EDIT: enabling nodeIntegration
fix the issue for me as well.
As of Electron version 5.0.0, nodeIntegration
is set to false by default. I came across the same error when using Angular 7+ and Electron 5. When I set nodeIntegration: true
everything works correctly.
I faced similar issue, but I fixed it by changing the code from :
win = new BrowserWindow({
width: 1200, height: 800,
});
To:
win = new BrowserWindow({
width: 1200, height: 800,
webPreferences: {
nodeIntegration: true,
backgroundThrottling: false
}
});
I've noticed that ipcRenderer is always null when I use any version of electron above 4. No matter what I set nodeIntegration to, ipcRenderer is always null. I suspect that this projects needs to be updated to support electron version 5+.
I've bumped ngx-electron
today and compiled it against Electon@6.0.10
in combination with Angular@8.2.x
.
Of course works ngx-electon
only with nodeIntegration:true
. This is due to the age of ngx-electron
.
Back in the days when writing ngx-electron
, nodeIntegration
was true
by default. Today, I consult you to dive deeper into Electron and use a custom preload script with tailored API being exposed to the Renderer. However, I fixed and tested the issues reported here. If you enable nodeIntegration, ipcRenderer
and others are available as expected @ctchisholm
Angular CLI: 8.3.25
Node: 12.14.0
OS: win32 x64
Angular: 8.2.14
... animations, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router
Package Version
-----------------------------------------------------------
@angular-devkit/architect 0.803.25
@angular-devkit/build-angular 0.803.25
@angular-devkit/build-optimizer 0.803.25
@angular-devkit/build-webpack 0.803.25
@angular-devkit/core 8.3.25
@angular-devkit/schematics 8.3.25
@angular/cli 8.3.25
@ngtools/webpack 8.3.25
@schematics/angular 8.3.25
@schematics/update 0.803.25
rxjs 6.4.0
typescript 3.5.3
webpack 4.39.2
Main elements of my directory structure:
electron/main.ts
electron/tsconfig.json
src/app/app.module.ts
src/app/app.component.ts
src/app/app.component.html
src/app/app.component.scss
angular.json
package.json
tsconfig.json
I have added to electron/main.ts:
function createWindow() {
win = new BrowserWindow({
width: 800,
height: 600,
icon: `file://${__dirname}/dist/assets/images/logo.png`,
webPreferences: {
nodeIntegration: true,
}
});
...
But, I still get the error:
TypeError: Cannot read property 'sendSync' of null
I am using the latest version of:
ngx-electron
My package.json:
{
"name": "color-palette",
"version": "0.0.0",
"main": "./electron/dist/main.js",
"build": {
"directories": {
"output": "./dist/"
},
"appId": "colorpalette1",
"category": "colorpalette1.app.color.histogarm",
"win": {
"target": "NSIS",
"icon": "build/icon.ico"
}
},
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e",
"start:electron": "ng build --base-href ./ && electron .",
"electron-build": "ng build --prod && electron .",
"dist": "ng build"
},
"private": true,
"dependencies": {
"@angular/animations": "~8.2.14",
"@angular/common": "~8.2.14",
"@angular/compiler": "~8.2.14",
"@angular/core": "~8.2.14",
"@angular/forms": "~8.2.14",
"@angular/platform-browser": "~8.2.14",
"@angular/platform-browser-dynamic": "~8.2.14",
"@angular/router": "~8.2.14",
"angular-svg-round-progressbar": "^3.0.1",
"gm": "^1.23.1",
"got": "^10.6.0",
"ngx-electron": "^2.2.0",
"rxjs": "~6.4.0",
"tslib": "^1.10.0",
"zone.js": "~0.9.1"
},
"devDependencies": {
"@angular-devkit/build-angular": "~0.803.21",
"@angular/cli": "~8.3.21",
"@angular/compiler-cli": "~8.2.14",
"@angular/language-service": "~8.2.14",
"@types/electron": "^1.6.10",
"@types/jasmine": "~3.3.8",
"@types/jasminewd2": "~2.0.3",
"@types/node": "~8.9.4",
"codelyzer": "^5.0.0",
"electron": "^8.1.1",
"electron-builder": "^22.4.1",
"electron-packager": "^14.2.1",
"jasmine-core": "~3.4.0",
"jasmine-spec-reporter": "~4.2.1",
"karma": "~4.1.0",
"karma-chrome-launcher": "~2.2.0",
"karma-coverage-istanbul-reporter": "~2.0.1",
"karma-jasmine": "~2.0.1",
"karma-jasmine-html-reporter": "^1.4.0",
"protractor": "~5.4.0",
"ts-node": "~7.0.0",
"tslint": "~5.15.0",
"typescript": "~3.5.3"
}
}
electron/tsconfig.json:
{
"compileOnSave": false,
"compilerOptions": {
"baseUrl": "./",
"outDir": "./dist",
"sourceMap": true,
"declaration": false,
"module": "commonjs",
"moduleResolution": "node",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"target": "es5",
"typeRoots": ["node_modules/@types"],
"lib": ["es2018", "dom"]
}
}
In VSCode, I am then adding the following into the terminal:
npm run start:electron
This works as expected, and opens up a new Chromium window.
I was then told to add:
npm start
Into the Chromium window's DevTool's console
But, I am a little bit confused by the last step?
https://dev.to/michaeljota/integrating-an-angular-cli-application-with-electron---the-ipc-4m18
Hey was getting the same when nodeIntegration was false and set it to true and now after that correction everything is returning undefined.
Angular version 10 electron version 10 and ngx-electron version 2.2.0
In my case only isElectronApp is true
all other properties are null or ReferenceError
npm 6.14.11 Angular CLI: 11.2.2 Node: 14.15.5 OS: win32 x64 Angular: 11.2.3
function createWindow() {
mainWindow = new electron.BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true,
enableRemoteModule: true,
backgroundThrottling: false,
preload: path.join(
electron.app.getAppPath(),
"dist/assets",
"preload.js"
),
},
});
mainWindow.loadURL(
url.format({
pathname: path.join(__dirname, `/dist/index.html`),
protocol: "file:",
slashes: true,
})
);
The same issue with angular 11 and ngx-electron 2.2.0
angular11, electron 12.0.7 and ngx-electron 2.2.0
I read the electron documentation and have found out, that the contextIsolation is by default true for securityreasons. contextIsolation must be false and nodeIntegration as already described must be true.
good luck
function createWindow () { mainWindow = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: true, contextIsolation : false } })
This was the answer I needed. Thank you!
angular11, electron 12.0.7 and ngx-electron 2.2.0
I read the electron documentation and have found out, that the contextIsolation is by default true for securityreasons. contextIsolation must be false and nodeIntegration as already described must be true.
good luck
function createWindow () { mainWindow = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: true, contextIsolation : false } })
the only correct answer for latest versions of electron and angular.
if somone need "electronService.remote" not to be null, also add "enableRemoteModule: true" to "webPreferences"
angular11, electron 12.0.7 and ngx-electron 2.2.0
I read the electron documentation and have found out, that the contextIsolation is by default true for securityreasons. contextIsolation must be false and nodeIntegration as already described must be true.
good luck
function createWindow () { mainWindow = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: true, contextIsolation : false } })
@lerchenreich I followed this solution but issue is not resolved in Angular version 13.3.3, electron version 19.0.4
I am trying to use desktopCaptures API in app.component.ts
if (this.electronService.isElectronApp) { this.electronService.desktopCapturer.getSources({ types: ['window', 'screen'] }).then(async sources => { // Other logic }); }
The desktopCapture function is coming undefined
Hi!
I created a new Angular 7 app with angular-cli and added your package, as well as the necessary electron packages. I also wired everything up. However, I was not able to communicate between ipcMain and ipcRenderer. In fact, Electron service always returns null when requesting an instance of ipcRenderer. Is this supposed to work with Angular 7?