Giter Club home page Giter Club logo

Comments (16)

lvbeck avatar lvbeck commented on June 18, 2024

I figure that out myself, in app.nsi I replace all "deskshell.exe" to "deskshell_debug.exe", and then repackage my application, then it will generate an executable file with debug mode.

but I still have some problem with the non-debug executable, I have written a nodejs native addon for my application, in this addon I use a third-party Windows COM(Component Object model) DLL to popup a new Windows Dialog/Form.

The problem is, my application will run perfectly in the debug mode, but it will fail in the non-debug mode after the Popup window call. I don't know the reason without debug information. @sihorton , do you have any idea?

from appjs-deskshell.

lvbeck avatar lvbeck commented on June 18, 2024

Hi @sihorton, I notice that you updated deskshell-debug.nsi to hide the nodejs debug console, so I checkout the newest deskshell.exe and deskshell_debug.exe, however both of them seems not working.

any help you can provide will be greatly appreciated.

from appjs-deskshell.

sihorton avatar sihorton commented on June 18, 2024

Sorry for the slow response here. It is a pain to debug the compiled executables. The NSIS compiler is actually quite nice although you are running in quite a limited environment. Basically it is possible to throw up msgbox with values so you can add them into the app.nsi that is generated for you and then hopefully at least see which line it is going wrong at. Most of the silent failures with the app.exe tend to be with missing paths. In this case though with the com object maybe it has some debug statements written to the console that no longer exists with the none debug version?

from appjs-deskshell.

lvbeck avatar lvbeck commented on June 18, 2024

thanks for your hint, but how to debug com object without console window?

from appjs-deskshell.

sihorton avatar sihorton commented on June 18, 2024

Ah maybe the problem is that the node.exe process is being started and then it is being run in a hidden window -- so your dll is opening the file picker but it is hidden. To test this theory instead of calling the com object code through a nodejs module directly instead use shell exec or similar to boot off node.exe passing it the filename of a nodejs script that uses the com object to pull up the file picker. Then the script can print out the selected filename or folder. This lets your application read the file that was select back from the output of the process. My guess is that then you will see the dialog that is currently being hidden.

So you would end up executing something like:
node.exe selectFolder.js
and it would then write out
{"filename":"c:\test.txt"}

from appjs-deskshell.

lvbeck avatar lvbeck commented on June 18, 2024

what do you mean by "boot off node.exe passing it the filename of a nodejs script that uses the com object to pull up the file picker" ? how can I call the com object in nodejs script? in my nodejs c++ addon, my com object has to be registered before use

from appjs-deskshell.

sihorton avatar sihorton commented on June 18, 2024

You have a nodejs native addon that you are using to open a window, I am guessing that the window is being opened, but it is hidden the same as the console window is being hidden. I am guessing that any windows you open from the nodejs process will also be hidden. To work around this and test the theory I am saying to move the call to the native addon to a separate process. So maybe now you have something like:-

var myAddon = require("COM-addonThing");
var filename = myAddon.openFilePicker();

I am suggesting that you change it for testing purposes to:-

var child = exec("node.exe openFilePicker.js",function(error,stdout,stderr) {
if(stderr) console.log("stderr: "+stderr);
if(stdout) console.log(stdout: "+stdout);
});

Then create a simple script openFilePicker.js

var myAddon = require("COM-addonThing");
var filename = myAddon.openFilePicker();
process.stdout.write('{"file":"' + filename + '"}\n\r");

So we are moving the call to the native add on to a separate process started via the command line and then we can see if you then see the native window. If this works then we have isolated exactly where the problem is coming from.

The NSIS exec had to have some special way of running the node.exe process in order to hide the console window and that is what is causing this new problem. If we could find another way to turn off the console window then we could use that instead in the exec, If I remember properly the problem is that node.exe is registered as a console application so when running it windows will automatically create a new console window for it to run within.

from appjs-deskshell.

lvbeck avatar lvbeck commented on June 18, 2024

thanks you @sihorton, I tested my code following your example:

var exec = require('child_process').exec,
child;
child = exec("node.exe run_myaddon.js",function(error,stdout,stderr) {
if(stderr) console.log("stderr: "+stderr);
if(stdout) console.log("stdout: "+stdout);
});

and I also try to execute run_myaddon.js in CMD directly:

node.exe run_myaddon.js

in both cases I did see the native COM object window, so the problem now should be NSIS exec?

from appjs-deskshell.

sihorton avatar sihorton commented on June 18, 2024

Ok great. I remember it took a lot of work and many different attempts to get the NSIS exec to hide the console window properly, I have been searching online but not found another solution to hide the console window. Therefore I can suggest a number of alternative solutions, maybe one will work well for your application:-

  1. You could pass a parameter from the nsis app.exe that you can then read in your app.js file, if the parameter -native-win-hack is set then do the child exec immediately but on yourself e.g.
    me = exec("node.exe app.js")
    this will then give you a new node.exe process and this second one will be able to open your native dialogs. So you first detect if you have been run from the app.exe and if so run yourself again then continue execution as normal. So the end process would be: app.exe -> deskshell -> app.js -> app.js so app.js starts itself running again. You have then got around native windows being hidden and can run as normal.

  2. I am guessing this will be used from your html application anyway, so you could start a second node process that opens a second port, then your html application can connect to both nodes and send gui related commands to the second node.exe and everything else to the first one. You could create a little javascript shim with an api that you call for each command and it then chooses which port to use so you don't need to know that within the html application.

  3. Keep the solution as it currently is, so when you want to do gui things you do it via a shell exec.

  4. You could run the second node.exe but keep it open, then as you get commands you want to run you write this to the process and it then replies for each command and outputs the result back, so this is more like an api where you are sending commands back and forwards between the two processes.

  5. Find a different way to prevent windows from opening the console window for you but do it without hiding other windows that are opened. We could swap out NSIS if you can find anything better to use instead. The main advantage with NSIS is that it is small and portable and you can compile exe files on the end users machine without having to install a big compiler environment so that was why I used it to create the .exe files.

  6. Create an HTML dialog instead of a native dialog for the file picking. Since you have nodejs and that has the built in fs module you can use the module to get a directory listing and return it as an array, then you could display that as html, so that you could browse and select a file. This would maybe be more work but would be prettier in the end perhaps?

Hopefully something there that can help you, if you think of a better solution please tell me.

from appjs-deskshell.

lvbeck avatar lvbeck commented on June 18, 2024

I test the first solution, but it does not work, here is my modified app.js file:

if(process.argv[2]=='-native-win-hack'){ // real run
var fs = require("fs");
var winfunc = require("deskshell-win-func");
var myaddon= require("myaddon/build/Release/myaddon");

var running = deskShell.startApp({
    "prompt_for_download": true
    //"user-data-dir":__dirname+"/data"
 }).then(function(app) {
            myaddon.run(); 
});

} else { // run in child process
var exec = require('child_process').exec,
child;
child = exec("node.exe app.js -native-win-hack",function(error,stdout,stderr) {
if(stderr) console.log("stderr: "+stderr);
if(stdout) console.log("stdout: "+stdout);
});
}

but node throw a error says:

Cannot not find module 'deskshell-win-func'

I guest it's somehow related to the execution path when deskshell call app.js, but I don't know how to fix it.

from appjs-deskshell.

sihorton avatar sihorton commented on June 18, 2024

Try setting the current working directory when calling the exec function.

child_process.exec(command, [options], callback)

so you should be able to do something like:
child = exec("node.exe app.js -native-win-hack",{
cwd:__dirname
},function(error,stdout,stderr) {});

You can also do: console.log(process.cwd()); to see where it is running from.

from appjs-deskshell.

sihorton avatar sihorton commented on June 18, 2024

The example code you showed does not actually use deskshell-win-func so maybe you could also just remove that line.

from appjs-deskshell.

lvbeck avatar lvbeck commented on June 18, 2024

I set the option cwd:__dirname in exec but it doesn't work either, throw a error "ReferenceError: deskShell is not defined", then I try something like this:

var environment = process.env;
environment.deskShell = deskShell;

child = exec("node.exe app.js -native-win-hack",{cwd:__dirname,env:environment},function(error,stdout,stderr) {
if(stderr) console.log("stderr: "+stderr);
if(stdout) console.log("stdout: "+stdout);
});

but still not working, can you tell me where and when is deskShell object created? How can I bypass this object into the child process?

the deskshell-win-func is used somewhere before myaddon.run(); I removed some of my code for better reading.

from appjs-deskshell.

sihorton avatar sihorton commented on June 18, 2024

deskshell.exe runs bin/win/deskshell.js on the local node.exe, this file reads the arguments and the app.desk configuration or application package file and then runs the application. deskshell.exe runs node using nsExec (http://nsis.sourceforge.net/Docs/nsExec/nsExec.txt) which suppresses the dos box (console). So rethinking the problem the simplest place to actually make this change would be on the first line of deskshell.js, something like the following (I am not at my computer so have not tested this):

if (process.argv does not contain -rebootHack) {
add -rebootHack to process.argv
exec(process.argv);
process.exit(0);
}

So basically the first time deskshell.js is run it will add a rebootHack flag to its arguments and restart itself. Hopefully your app can then open its windows.

To make the implementation nicer we could add support for this in the app.desk file. The deskshell.js file could read the application json file (it already does this) and check for the existence of a property, so there is a line in the deskshell.js file:
switch(deskShell.appDef.backend) {
before this line we could add
if (deskShell.appDef.nativeWindowsFix) {
and then do the same as above, i.e. restart the application again. I would be happy to add this to deskshell and release a new version with the fix in. All that is then required is to add nativeWindowsFix: true to the applications app.desk file and it should then run. This will add some milliseconds to the startup time of the app but otherwise should work nicely.

from appjs-deskshell.

lvbeck avatar lvbeck commented on June 18, 2024

Great, it works! Thank you @sihorton so much!! I will send you a merge request ASAP to share the fix.

from appjs-deskshell.

sihorton avatar sihorton commented on June 18, 2024

Great, glad we managed to get to the bottom of the problem in the end!

from appjs-deskshell.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.