ipcRenderer not receiving message from main process - electron

I can see the "Hello from renderer" alert, but not the "Goodbye from renderer" alert.
Running in Windows 10.
And I can't see the "received!" alert, which I should see it the ipcRenderer.on(...) worked.
index.js
const { app, BrowserWindow} = require("electron");
app.on('ready', () => {
let mainWindow = new BrowserWindow(
{
width: 800,
height: 600,
});
mainWindow.loadURL(`file://${__dirname}/index.html`);
mainWindow.webContents.on('did-finish-load', () => {
mainWindow.webContents.send("from-main", "teste");
});
});
index.html
<html>
<head>
<title>test</title>
<script src="./renderer.js"> </script>
</head>
<body>
Wait...
</body>
</html>
renderer.js
alert('hello from renderer');
const { ipcRenderer } = require('electron');
ipcRenderer.on('from-main', () => { alert('received!');} );
alert('goodbye from renderer');
package.json
{
"name": "xxx",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "electron ."
},
"author": "",
"license": "ISC",
"dependencies": {
"electron": "^8.0.0"
}
}

let mainWindow = new BrowserWindow(
{
width: 800,
height: 600,
webPreferences:{
nodeIntegration:true
}
});
Please add nodeIntegration when you are creating the browser window.
You are using the Node API at your renderer. When you don't enable nodeIntegration then you won't be able to use any node modules at your renderer js.
To confirm this you can see this error message from your app debug console.
mainWindow.webContents.on('did-finish-load', () => {
// open dev tools
mainWindow.webContents.openDevTools()
mainWindow.webContents.send("from-main", "teste");
});
Uncaught ReferenceError: require is not defined
This means you didn't enable the nodeIntegration when you are creating the browserWindow.

Related

Electron App - How do i open link in browser?

im trying to open a link in a new browser window using a Electron App.
const test = () => {
const shell = window.require('electron').shell;
shell.openExternal("https://google.com");
}
When i do this, i get error "window.require is not a function"
I have ofcourse made my research on this, and found several "fixes" but none has worked for me. I have edited my webpack.config.js to this:
module.exports = {
configureWebpack: {
externals: {
'./cptable': 'var cptable'
},
resolve: {
fallback: {
'fs': false,
'crypto': false,
'path': false,
}
}
},
}
I have also made sure nodeIntegration enabled like so:
const mainWindow = new BrowserWindow({
width: 1280,
height: 720,
webPreferences: {
nodeIntegration: true
},
autoHideMenuBar: true,
resizable: false,
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})
```
still no success. any idea?
renderer.js - from your renderer send request.
const response = await window.electronAPI.openLinkPlease()
preload.js - you have this middleware where your request will receive to send to electron.
process.once("loaded", () => {
contextBridge.exposeInMainWorld('electronAPI', {
openLinkPlease: () => ipcRenderer.invoke('openLinkPlease'),
})
});
electron.js - here you will get your request to open and electron will open this url in your default browser.
First add at the very beginning const {shell} = require("electron"); to add shell capabilities and than after
preload: path.join(__dirname, 'preload.js'),
},
});
add
ipcMain.handle('openLinkPlease', () => {
shell.openExternal("https://google.com");
})
This is the screen how it works from my application

How can I troubleshoot why electron-builder isn't creating a working production package

My app builds fine on local, but when I try to create a production version, I'm having trouble. I'm not very well versed in either electron or electron-builder, so this could definitely be something simple I'm missing.
My project packages successfully, and when I open it from Finder (I'm on a mac) the window launches properly, but nothing renders; this is the result:
Previously (with different mucking around) I've had an error 'not allowed to access local file:' and then gives me a directory path.
Here is my package.json:
"main": "public/electron.js",
"name": "storyweaver-dm",
"version": "0.1.0",
"private": true,
"dependencies": {
"#testing-library/jest-dom": "^4.2.4",
"#testing-library/react": "^9.3.2",
"#testing-library/user-event": "^7.1.2",
"axios": "^0.19.2",
"concurrently": "^5.1.0",
"electron-is-dev": "^1.1.0",
"nodemon": "^2.0.4",
"react": "^16.13.0",
"react-beautiful-dnd": "^13.0.0",
"react-dom": "^16.13.0",
"react-hook-form": "^6.1.2",
"react-scripts": "3.4.0",
"react-select": "^3.1.0",
"recoil": "0.0.10",
"sqlite3": "^5.0.0",
"styled-components": "^5.0.1",
"wait-on": "^4.0.1"
},
"devDependencies": {
"#rescripts/cli": "^0.0.13",
"#rescripts/rescript-env": "^0.0.11",
"electron": "^8.1.1",
"electron-builder": "^22.4.1",
"electron-devtools-installer": "^2.2.4",
"typescript": "^3.8.3"
},
"homepage": "./",
"scripts": {
"build": "rescripts build",
"eject": "react-scripts eject",
"electron-dev": "concurrently \"BROWSER=none yarn start\" \"wait-on http://localhost:4203 && electron .\"",
"dev": "concurrently \"BROWSER=none npm start\" \"wait-on http://localhost:4203 && electron .\"",
"electron-pack": "electron-builder build -mw",
"postinstall": "electron-builder install-app-deps",
"preelectron-pack": "npm install",
"start": "PORT=4203 rescripts start",
"test": "rescripts test"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"rescripts": [
"env"
],
"author": {
"name": "Jamie Sauve and other wonderful people",
"email": "jamiesauve#zohomail.com"
},
"build": {
"appId": "com.my-website.my-app",
"productName": "StoryWeaver DM",
"copyright": "Copyright © 2019 ${author}",
"mac": {
"icon": "./assets.icon.icns",
"category": "public.app-category.utilities"
},
"files": [
"public/**/*",
"build/**/*",
"node_modules/**/*",
"pseudoServer/**/*",
"./public/electron.js"
],
"directories": {
"buildResources": "assets"
}
}
}
and here is my electron.js (I renamed this - this is my main Electron process):
const electron = require('electron');
const app = electron.app;
const ipcMain = electron.ipcMain;
const BrowserWindow = electron.BrowserWindow;
// const { default: installExtension, REACT_DEVELOPER_TOOLS } = require('electron-devtools-installer');
const path = require('path');
const isDev = require('electron-is-dev');
process.env['APP_PATH'] = app.getAppPath();
const directory = isDev ? process.cwd() : process.env.APP_PATH;
const databaseApi = require(path.join(directory, './pseudoServer/api/controller/routes'))
ipcMain.handle('dbRequest', async (event, request) => {
const response = await databaseApi(request)
return response
})
let mainWindow;
function createWindow() {
mainWindow = new BrowserWindow({
webPreferences: {
nodeIntegration: false,
webSecurity: false,
/**
* import native Node modules explicitly in this file; something about Create-React-App and webpack mess
* with Electron's ability to provide these directly.
* See the comment by HemalR here: https://github.com/electron/electron/issues/9920
*/
preload: __dirname + '/preload.js'
},
});
mainWindow.maximize();
mainWindow.loadURL(isDev ? 'http://localhost:4203' : `file:///${__dirname}/public/index.html`)
if (isDev) {
// Open the DevTools.
//BrowserWindow.addDevToolsExtension('<location to your react chrome extension>');
mainWindow.webContents.openDevTools();
// installExtension(REACT_DEVELOPER_TOOLS)
// .then((name) => console.log(`Added Extension: ${name}`))
// .catch((err) => console.log('An error occurred: ', err));
}
mainWindow.on('closed', () => mainWindow = null);
}
app.on('ready', createWindow);
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});
app.on('activate', () => {
if (mainWindow === null) {
createWindow();
}
});
and this is my index.html:
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<!-- see https://github.com/electron/electron/issues/19775 for the line below -->
<meta http-equiv="Content-Security-Policy" content="default-src *; style-src 'self' http://* 'unsafe-inline'; script-src 'self' http://* 'unsafe-inline'" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<base href="./" />
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>StoryWeaver DM</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>
How can I get this app packaging properly in production?
The /pseudoServer directory might be an odd pattern - I'm using a sqlite3 database, and created a 'server' (really just called from the electron main process) to access it. I'm not sure if this actually counts as a backend or not in Electron.
My project is at https://github.com/jamiesauve/StoryWeaver-DM if these two files don't provide enough information.

firefox extension with native messaging application not working

I have a native application developed in Java (compiled jar) , the extension basically sends message to the native application with the user input and get response back into a label on to the web page.
The extension is working fine with Chrome but I am not able to execute the same in Firefox 58.0.1(quantum 64 bit).
Error in the browser console.
can not convert null to object
below is the snippet code and the error screenshots.
{
"manifest_version":2,
"name":"Firefox Automation Extension",
"version":"1.0",
"description":"Automation Extensions",
"icons": {
"16": "icons/synergy.png"
},
"browser_action":{
"default_icon": {
"32" : "icons/synergy.png"
},
"default_title": "Native Messaging Application Testing",
"default_popup": "index.html"
},
"background":{
"scripts": ["background.js"]
},
"applications": {
"gecko": {
"id": "webdom#oracle.com",
"strict_min_version": "58.0"
}
},
"content_security_policy":"script-src 'self' 'unsafe-eval'; object-src 'self'",
"permissions": [
"nativeMessaging", "<all_urls>"
],
"content_scripts": [
{
"matches": [
"<all_urls>"
],
"js": [
"jquery-1.12.2.min.js",
"contentScript.js"
]
}
]
}
/* background.js */
browser.runtime.onMessage.addListener(function (msg, sender, sendResponse) {
console.info("Received %o from %o, frame", msg, sender.tab, sender.frameId);
// As it is registered in registy
var host_name="xxxxxxxxxxxxxxxxxxx";
// Open port (for communication).
var port = browser.runtime.connectNative(host_name);
// Send message to native application.
port.postMessage(msg);
// Listen for response...
port.onMessage.addListener(function (msg) {
// Send data to the content.
browser.tabs.query({ active: true, currentWindow: true }, function (tabs) {
browser.tabs.sendMessage(tabs[0].id, msg, function (response) { });
});
});
port.onDisconnect.addListener(function () {
console.info("Disconnected.");
});
});
/* contentScript.js */
document.addEventListener("send-message-event", function (data) {
var request = data.detail.data;
console.log("content script : ", request);
// Send message to the background script
browser.runtime.sendMessage(request, null);
});
/**
* Listens to the background script and dispatches 'get-message-event'
* to the client when the data is received.
*/
browser.runtime.onMessage.addListener(function (response, sender, sendResponse) {
console.log(response);
// Send response to the front page
var event = new CustomEvent("get-message-event", {
detail: {
data: response
},
bubbles: true,
cancelable: true
});
document.dispatchEvent(event);
});
/* Main.js (script called from a html page )*/
$(document).ready(function () {
var sendMessageBtn = $('#send-message-button');
var inputElem = $('#input-text');
var responseElem = $('#response');
/**
* Send message operation
*/
sendMessageBtn.click(function () {
var request = {};
request.message = inputElem.val();
var event = new CustomEvent("send-message-event", {
detail: {
data: request
},
bubbles: true,
cancelable: true
});
console.log("From Main : ",event.detail.data);
document.dispatchEvent(event);
});
/**
* Get message event listener
*/
document.addEventListener("get-message-event", function (data) {
var responseObject = data.detail.data;
responseElem.text(responseObject.message);
});
});
index.html page
<!DOCTYPE html>
<html>
<head>
<title>Native Messaging</title>
<meta charset="utf-8">
<link rel="stylesheet" href="bootstrap.min.css">
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-4"></div>
<div class="col-md-4">
<div class="page-header">
<h2>Native Messaging</h2>
</div>
<div class="form-group">
<label for="input-text">Input message:</label>
<input class="form-control" id='input-text' type='text' value="Test" />
</div>
<button type="button" class="btn btn-block btn-default" id='send-message-button'>Send Message</button>
<hr>
<div class="well well-lg" id='response'>Response from Native app...</div>
</div>
<div class="col-md-4"></div>
</div>
</div>
<!-- jQuery and JS files -->
<script src="jquery-1.12.2.min.js"></script>
<script src="main.js"></script>
</body>
</html>
While clicking on the send Message button I am getting can not convert null to object error.
the code is working fine in Chrome and i am able to get response from the Native application in chrome extension
I think the problem is because you have not registered your native application in regedit in:
HKEY_LOCAL_MACHINE\SOFTWARE\Mozilla\NativeMessagingHosts
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Mozilla\NativeMessagingHosts
I would put in permission :
"tabs",
"nativeMessaging",
"<all_urls>",
"webNavigation"
to work with your browser.

tfs extension with menu control childs - childs not showing

I'm trying to create extension which allow me to open a work item context menu and see new control and when I hover on the control a sub menu will open. just like the way 'Move to iteration' and 'Templates' works.
this is the contributions section of my vss-extension.json:
"contributions": [
{
"id": "releaseMenuAction",
"type": "ms.vss-web.action",
"description": "test",
"targets": [
"ms.vss-work-web.backlog-item-menu",
"ms.vss-work-web.work-item-context-menu"
],
"properties": {
"name": "releaseMenuAction",
"text": "Assign to release",
"title": "Assign to release",
"icon": "img/delivery_small.png",
"uri": "index.html"
}
}
]
and this is the html page:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="sdk/VSS.SDK.min.js"></script>
</head>
<body>
<script>
VSS.init({ usePlatformScripts: true, usePlatformStyles: true, explicitNotifyLoaded: true });
// Use an IIFE to create an object that satisfies the IContributedMenuSource contract
var menuContributionHandler = (function () {
"use strict";
return {
getMenuItems: function (actionContext) {
var subMenus = [
{
text: "one",
action: function (actionContext) {
alert("one");
}
},
{
text: "two",
action: function (actionContext) {
alert("two");
}
}
];
return [
{
text: "Assign to release",
group: "actions",
icon: "img/delivery_small.png",
childItems: subMenus
}
];
}
};
}());
// Associate the menuContributionHandler object with the "releaseMenuAction" menu contribution from the manifest.
VSS.register("releaseMenuAction", menuContributionHandler);
</script>
</body>
</html>
The result I'm getting is only to see the 'Assign to release' control in the menu but without his childs.
What am I missing?
Thanks.
#PatrickLu-MSFT Thanks for the reply.
I managed to solved the problem. I was missing a line in the code:
VSS.notifyLoadSucceeded();
this line "tells" the tfs that the extension loaded succesfully.

Angular component not executing with Webpack

Short Version:
I'm building an app with Angular2 and Webpack. I have the bundles building successfully, but when I include them on my page, the angular components loading. No errors are showing up.
webpack.config.js
"use strict";
let webpack = require('webpack');
let ExtractTextPlugin = require('extract-text-webpack-plugin');
let helpers = require('./webpack.helpers.js');
let HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
'app': helpers.root('/Modules/Shared/Main.ts'),
'vendor': helpers.root('/External/Vendor.ts'),
'polyfills': helpers.root('/External/Polyfill.ts')
},
devtool: 'source-map',
resolve: {
extensions: ['.ts', '.js', '.json', '.css', '.scss', '.html']
},
output: {
path: helpers.root('/wwwroot/scripts'),
filename: '[name].js'
},
module: {
rules: [
{
test: /\.ts$/,
loaders: [
{ loader: 'awesome-typescript-loader', options: { tsConfig: 'tsconfig.json' } },
'angular-router-loader',
'angular2-template-loader',
'source-map-loader',
'tslint-loader'
]
},
{
test: /\.(png|jpg|gif|woff|woff2|ttf|svg|eot)$/,
loader: 'file-loader?name=assets/[name]-[hash:6].[ext]'
},
{
test: /favicon.ico$/,
loader: 'file-loader?name=/[name].[ext]'
},
{
test: /\.css$/,
loader: ExtractTextPlugin.extract({
fallbackLoader: "style-loader",
loader: "css-loader"
})
},
{
test: /\.scss$/,
exclude: /node_modules/,
loaders: ['style-loader', 'css-loader', 'sass-loader']
},
{
test: /\.html$/,
loader: 'raw-loader'
}
]
},
plugins: [
new ExtractTextPlugin('css/[name].bundle.css'),
new webpack.NoEmitOnErrorsPlugin(),
// Workaround for angular/angular#11580
new webpack.ContextReplacementPlugin(
// The (\\|\/) piece accounts for path separators in *nix and Windows
/angular(\\|\/)core(\\|\/)#angular/,
'Modules/', // location of your src
{} // a map of your routes
),
new webpack.optimize.CommonsChunkPlugin({
name: ['app', 'vendor', 'polyfills']
}),
new webpack.ProvidePlugin({
jQuery: 'jquery',
$: 'jquery',
jquery: 'jquery',
}),
new HtmlWebpackPlugin()
]
};
tsconfig.json
{
"compilerOptions": {
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"module": "commonjs",
"moduleResolution": "node",
"noEmitOnError": true,
"noImplicitAny": true,
"removeComments": true,
"skipLibCheck": true,
"sourceMap": true,
"target": "es5"
},
"exclude": [
"node_modules",
"wwwroot"
],
"compileOnSave": true
}
The files are being generated correctly:
http://imgur.com/a/xzw0E
_Layout.cshtml
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>#ViewData["Title"]</title>
<base href="/" />
</head>
<body style="background-color: #333;">
#RenderBody()
<script type="text/javascript" src="/scripts/polyfills.js"></script>
<script type="text/javascript" src="/scripts/vendor.js"></script>
#RenderSection("scripts", required: false)
</body>
</html>
index.cshtml
#using System.Threading.Tasks
#{
ViewData["Title"] = "Home Page";
}
<div style="height: 100%;">
<app-component>Loading...</app-component>
</div>
#section Scripts{
<script type="text/javascript" src="/scripts/app.js"></script>
}
The component I'm expecting to see looks like this:
import { Component } from '#angular/core';
#Component({
selector: 'app-component'
})
export class AppComponent {
constructor() {
console.log('I\'m running !!!!');
}
}
But when I generate the page, it looks like this:
http://imgur.com/a/YrPJf
with no errors in the console:
http://imgur.com/a/Xepl2
Any help is greatly appreciated
Seems you forgot about bootstrapping your application via
platformBrowserDynamic().bootstrapModule(AppModule);

Resources