Api suggestion: API.App.restart #149
peters posted onGitHub
Support for restarting the application. It should restart with the same invocation flags it was started with in the first place. This would be great when it comes to auto-updating.
<bountysource-plugin>
Want to back this issue? Post a bounty on it! We accept bounties via Bountysource. </bountysource-plugin>
Can't you just refresh the page?
document.location.reload(true)
Sure, you could do that. But what if the application holds an exclusive lock on a file you are going to update? What if you want to replace the chromium binary blob itself?
+1
I'll implement App.restart()
after #64 is done.
+1
Any thoughts / priority on this restart API? Would be great.
+1 for a clean restart function
Any updates on this feature?
+1 for this!
+1 It would be nice to auto update applications.
This feature would be helpful when doing updates, as you can provide the user with a button to restart the application instead of asking them to close and reopen.
It is a real nuisance to do this with shell scripts. Since after you've spawned the script you'll have to wait until the app process terminates. And it is hard to do right path parameter sanitising (e.g. spaces). Not to mention Unicode text which I believe is not supported on Windows, or is it? The Windows shell script:
@echo off
rem usage: relaunch_app.bat <seconds to wait> <executable to launch> <arguments>
rem i.e. $>relaunch_app.bat 5 "C:\Program Files\Jujusoft\JujuEdit\JujuEdit.exe" "C:\Windows\system.ini"
echo Restarting in %1 seconds...
title Waiting
rem Windows 7
@timeout /t %1 /nobreak >nul 2>&1
rem Windows XP
if errorlevel 1 ping 192.0.2.2 -n 1 -w %1000 > nul
rem # launch the executable via start command
start /B "" %2 %3 %4
And on Mac:
echo "Please wait for ${1} seconds.."
sleep $1
open -n -a "${2}" --args $3
In your node-webkit app:
child_process.spawn(path.join(process.cwd(), "relaunch_app.bat")
, [waitSecs.toString()
, (process.platform == "darwin") ? process.execPath.match(/^([^\0]+?\.app)\//)[1]
: process.execPath
]
, {detached: true}
);
现在只能在工具条上点击, 如何在程序中调用 restart 呢
用 document.location.reload(true) 代替是不是不能刷新node的模块?
What about: require('nw.gui').Window.get().reload(3); It will do clean-reload, like the rightmost reload button on toolbar, right?
@f0rmiga No, unfortunately that doesn't work. If your app consists of more than one window, only the window from which that command is run is reloaded. Ideally, App.restart or its equivalent would restart the entire app by shutting down all windows associated with the app.
+1
@james: you could send a notification to that window so it can reload itself too.
micha
2014-02-27 1:11 GMT+01:00 Paul Mandel notifications@github.com:
+1
— Reply to this email directly or view it on GitHubhttps://github.com/rogerwang/node-webkit/issues/149#issuecomment-36194978 .
+1
+1
+1
+1
@f0rmiga - You wrote:
require('nw.gui').Window.get().reload(3);
I had no idea the method accepted arguments. It's not in the wiki. It helped me out. What does it control?
One or two of the 'Window.reload' family methods aren't documented either. Like this one:
Window.prototype.reloadDev()
Which, funnily enough, resolves to a nested call to reload(3)...
@dynamite-ready I'm sorry, but I don't remember where I found it and what exactly it controls, but it worked to me pretty well. I made a app that uses just one window and it connects to a server, and all other solutions that I tried did not reloaded the connection to the server for example, but that method did it... maybe in other scenarios, like @jamesmortensen said, it won't work. More specifically when you have more than 1 window.
Actually this works perfect for me, a simple respawn of itself:
//Restart node-webkit app
var child_process = require("child_process");
//Start new app
var child = child_process.spawn(process.execPath, [], {detached: true});
//Don't wait for it
child.unref();
//Quit current
GUI.window.hide(); // hide window to prevent black display
GUI.app.quit(); // quit node-webkit app
@gpetrov I can't get this to work on OS X. I did alter the spawn
call to use the .app
path that is common on OS X, but that didn't work. It does close the app, and does not throw an error, but the spawn doesn't launch the app again.
If I use it as-is (not altering the exePath to point to the actual .app
folder), it launches node-webkit again, but does not load any of my specific web assets, just the plain node-webkit window that you see when it can't find your web assets.
Any ideas?
In the meantime, I think I'm going to try @semmel 's method.
i tested the spawn method the problem (0.10) seems that the .unref on the child is not working i tried it with say and delay. app does not quit until the delay on the spawned process and say command happens
this is my bash test script content
sleep 5 say 'hi there'
but if you run the same thing on plain node works.
ok got it working
restart file on bash
sleep 1 open -n {appPath}
from the app.
r = spawn(process.cwd() + '/restart', [], {detached:true}); r.unref(); process.exit();
+1
It would be good if App.restart()
could took arguments which would be passed to the restarting app (i.e. argv
).
+1
is the App.restart() implemented yet?
App.restart = function() {
var child,
child_process = require("child_process"),
gui = require('nw.gui'),
win = gui.Window.get();
if (process.platform == "darwin") {
child = child_process.spawn("open", ["-n", "-a", process.execPath.match(/^([^\0]+?\.app)\//)[1]], {detached:true});
} else {
child = child_process.spawn(process.execPath, [], {detached: true});
}
child.unref();
win.hide();
gui.App.quit();
}
+1
@fov42550564 that worked for me. thanks!
+1!
Having an issue on 0.12.2 where this code will restart the application, but the newly spawned app crashes and you have to force quit.
The application window is displayed and sized but nothing is displayed.
I have tracked this down -- on application startup, I do a gui.App.clearCache(). When I restart the application it appears to freeze on this line.
If I add a timeout, an alert or remove this line, the application does not freeze and restarts as normal.
Hopefully that might help out someone
@gpetrov , Thanks for the commenting , your code works good .
@fov42550564 that works, but with a flaw:
On its first run, my application determines the path to the Pepper Flash plugin of Google Chrome. If it finds it, it updates the package.json (inserts chromium args for ppapi-flash) and does a restart like you proposed.
Then during that second start (the restart), the updated package.json is being loaded, but not the plugin. It seems that the child process uses the newly created package.json but fails to initialize the plugin properly.
If I exit and restart manually, the plugin is being loaded and can be used.
So I give a "+1" for this request, and demand for a very clean restart that even loads changes to plugins. :)
Until then, I'll have to find a different approach (perhaps with that batch script mentioned above).
@fov42550564 Nevermind, I was experiencing a race condition. The updated package.json was written a few milliseconds too late to disc. Now it works. :)
I can confirm @gpetrov's / @fov42550564's way worked. We tested with https://gist.github.com/adam-lynch/bdb7f74a57f26e30a3fd and NW.js 0.12.2 on Windows 7, 8.1, Mac OS X Mavericks & Yosemite.
+1
@fov42550564's solution didnt work on my osx.
after relaunch it gave me
"Uncaught Error: Cannot find module 'nw.gui'", source: module.js (338)
add my +1 to App.restart, too
in my index.html
<script src="./code/app.js"></script>
in my app.js
require('nw.gui').App.restart = function() {
var child
var child_process = require("./code/app.js")
var gui = require('nw.gui')
var win = gui.Window.get()
if (process.platform == "darwin") {
child = child_process.spawn("open", ["-n", "-a", process.execPath.match(/^([^\0]+?\.app)\//)[1]], {detached:true})
} else {
child = child_process.spawn(process.execPath, [], {detached: true})
}
child.unref()
win.hide()
gui.App.quit()
}
setTimeout(function () {
require('nw.gui').App.restart()
}, 2*1000)
Application launches fine and crashes after 2 seconds (on App.restart) with output
[11948:1028/112029:ERROR:nw_shell.cc(336)] Error: Cannot find module 'nw.gui'
at Function.Module._resolveFilename (module.js:327:15)
at Function.Module._load (module.js:264:25)
at Module.require (module.js:356:17)
at require (module.js:375:17)
at Object.<anonymous> (/Users/michelek/Documents/github/Screenwerk/code/app.js:6:23)
at Module._compile (module.js:451:26)
at Object.Module._extensions..js (module.js:469:10)
at Module.load (module.js:346:32)
at Function.Module._load (module.js:301:12)
at Module.require (module.js:356:17)
[11948:1028/112029:INFO:CONSOLE(327)] "Uncaught Error: Cannot find module 'nw.gui'", source: module.js (327)
There is a context problem as I'm not reloading my index.html
I can't child_process = require("./index.html")
Any ideas?
+1
@mitselek i have the same error on fedora 22
A long-awaited feature, indeed. Is there some hope for it to be implemented?
+1 to this feature from me too! https://i.gyazo.com/23171745df3aa4ac77ced7901c44b5f8.gif :+1:
+1
chrome.runtime.reload();
@iteufel, it ends up with "Unchecked runtime.lastError while running runtime.restart: Restart is only supported on ChromeOS".
@xenohunter Use chrome.runtime.reload
not chrome.runtime.restart
@iteufel Thank you very much! It works like a charm.
@iteufel, oops. Though now it takes no effect at all. No warning, no error, just nothing.
+1
+1
if anyone is interested, i've solved it like this
restart() {
const {execPath, platform} = nw.process;
const {resolve} = nw.require('path');
let exePath = '';
let restartFile = '';
let command = '';
let content = '';
const {tmpdir} = nw.require('os');
const TEMP_DIR = resolve(tmpdir(), 'YOUR APP NAME');
if (platform === 'darwin') {
exePath = resolve(execPath, '../../../../../../../');
restartFile = resolve(TEMP_DIR, 'restart.sh');
content = "#!/bin/sh\nAPP=$1\nsleep 1\nopen $APP";
command = 'sh ';
} else {
exePath = execPath;
restartFile = resolve(TEMP_DIR, 'restart.bat');
content = "timeout 2\ncall $1";
command = '';
}
const fs = nw.require('fs');
fs.writeFile(restartFile, content, function (err) {
child_process.exec(command + restartFile + ' ' + exePath);
nw.App.quit();
});
}
@blaremc did you test it on windows? Doesn't work for me, seems like child_process.exec
does nothing on windows.
For me, solution provided by @gpetrov worked on windows (tested in win7 & win10) and solution from @blaremc (slightly modified) worked on linux
@GendelfLugansk this code is working
restart() {
let exePath = '';
const {resolve} = nw.require('path');
const {execPath, platform} = nw.process;
if (platform === 'darwin') {
exePath = resolve(execPath, '../../../../../../../');
} else {
exePath = execPath;
}
this.createRestartFile(exePath, () => {
setTimeout(() => {
nw.App.quit();
}, 300);
});
}
createRestartFile(exePath, callback) {
const {platform} = nw.process;
const {resolve} = nw.require('path');
let restartFile = '';
let command = '';
let content = '';
const TEMP_DIR = this.getTempDir();
if (platform === 'darwin') {
restartFile = resolve(TEMP_DIR, 'restart.sh');
content = "#!/bin/sh\nAPP=$1\nsleep 3\nopen $APP";
command = 'sh ';
} else {
restartFile = resolve(TEMP_DIR, 'restart.bat');
content = "timeout 3\nstart %1\nexit\n";
command = 'start /b ';
}
const fs = nw.require('fs');
fs.writeFile(restartFile, content, function (err) {
child_process.exec(command + restartFile + ' ' + exePath);
callback();
});
}
try chrome.runtime.reload();
As mentioned by surinder: chrome.runtime.reload();
should work I believe it is the code underlying Reload app context menu in sdk versions.
@mscreenie As was mentioned before by few users, chrome.runtime.reload();
does not fully restart webkit, which is required for tasks like application update or ffmpeg update. Old versions of ddl/so will be used until app fully restarted (meaning - closed and started again)
Works
chrome.runtime.reload()
works for me.
@loadbalance-sudachi-kun funded this issue with $256. Visit this issue on Issuehunt
chrome.runtime.reload() does not work at this time. seems like localStorage doesn't get loaded the same way afterwards
any new?, document.location.reload(true);
seem buggy with vscode debugger
I lost break point
if(event.keyCode === 116){ // F5 refresh
document.location.reload(true);
};
"version": "0.1.0",
"configurations": [
{
"type": "nwjs",
"request": "launch",
"name": "NWJS DEBUG",
"runtimeExecutable": "${workspaceRoot}\\_NW\\sdk\\nw.exe",
"runtimeArgs": [
"--remote-debugging-port=9222",
"--enable-gpu-rasterization",
"--enable-gpu-memory-buffer-video-frames",
"--enable-native-gpu-memory-buffers",
],
"webRoot": "${workspaceRoot}",
"port": 9222,
"sourceMaps": false,
"reloadAfterAttached": true,
},
{
"type": "nwjs",
"request": "attach",
"name": "Attach to NWjs",
"port": 9222,
"webRoot": "${workspaceFolder}",
"reloadAfterAttached": true,
}
]
+1 It seems there are enough uses cases to just expose either the old win.reloadDev()
or API.App.restart
. Also, the website still mentions win.reloadDev()
..