Opening an excel file with opn while another excel file is open, will execute code immediately without waiting - node.js

I'm using a library called opn. This makes it easier to spawn a child process to open a file in the main process of electron. I could use shell but I need to be able to detect when the file is closed which shell API doesn't provide.
Whenever I open an excel file and there are no other excel files opened, it will work fine and it will wait until I close the file before it resolve the promise. However, if there are other excel files open then it won't wait for the file to be closed and it will resolve the promise immediately.
I did some digging in the source code of the library and the command used to open the file is this for windows: start "" /wait name_of_file where name_of_file is a place holder for the file. The actual command the library executes is different but this one is enough for my use case. I ran into the same problem even when doing it manually without using the library. Maybe I should post this under super user instead of stackoverflow.
Here is the code that opens the file, wait for the file then executes callback.
opn(file, { app: 'EXCEL', wait: true }).then(() => {
const stream = fs.createReadStream(file);
papa.parse(stream, {
delimiter: ',',
complete: (results) => {
mainWindow.webContents.send('uploadNewIndexFileRen', key,
results.data);
},
error: (err) => {
throw err;
}
});
}).catch((error) => { throw error; });
UPDATE:
Here is a quick nodejs repo. All you need to do is clone/fork to check the problem or make a pull request then do npm install to download needed packages. To reproduce the exact problem that I have you might need to be in the following software versions:
Window 10
npm 5.5.1
node v8.9.1
excel 2013
opn 5.2.0 as seen in package.json

This is probably due to the way Excel handles files. I'm guessing Excel handles files with a single process so subsequent opening of files simply signals to the existing process that another files needs opening before closing.
You may be able to force Excel to open a new instance for each file by following these instructions.
Apparently using the /x command line switch will also start a new process:
excel.exe /x

Related

Worker thread postMessage() vs command line command

I recently learned about Worker threads in Node JS. I was trying to create a worker thread to run Stockfish chess engine in node js.
The npm package I am using for this is called stockfish. I tried using node-stockfish before this but it was not installing with npm as it was using an older version of the type definition for the "AbortSignal" variable apparently causing compatibility issues.
For the current npm package that I am using even though I was able to install it successfully, I could find very little documentation on how to use it. So I tried out a few ideas.
import { Worker } from "worker_threads";
const engine = new Worker("./node_modules/stockfish/src/stockfish.js")
engine.on('message', (data) => console.log(data))
engine.postMessage('position startpos move e2e4 e7e5')
engine.postMessage('go movetime 3000')
Here I tried to run the stockfish.js as a worker thread and send commands to it with the postMessage() function. This however did not work and it gave the following output:
worker.js received unknown command undefined
position startpos move e2e4 e7e5
worker.js received unknown command undefined
go movetime 3000
But I know these commands are valid commands if I run the same js from the command line like so:
It might be because I am using the flags --experimental-wasm-threads and --experimental-wasm-simd when I am running it from the command line. I found this command to run it from the little documentation that was present. But I don't know how to mention these flags when I run it through a worker thread.
Otherwise it could also be that I don't understand how worker threads work yet and postMessage() is not the same as sending it a command from the command line.
Any help is greatly appreciated.
I switched to using stockfish.wasm library instead. With this library I was able to achieve what I wanted and I don't need to use any worker threads for now. Maybe I can add this to a worker thread if required later. Here is a simple example:
const Stockfish = require("stockfish.wasm")
Stockfish().then((engine) => {
engine.addMessageListener((output) => {
console.log(output);
// Do something with the output data here
})
engine.postMessage("uci");
engine.postMessage("ucinewgame");
engine.postMessage("position startpos");
engine.postMessage("go depth 20");
});

EBUSY error when downloading and executing a .exe file with Node.js

I'm trying to download an executable file with Node.js and execute it as soon as the file is downloaded. I should launch it using the spawn method because I want the new process to be detatched. This is what I have done:
var file = fs.createWriteStream("myex.exe")
http.get("http://host/myex.exe", function(response) {
response.pipe(file);
const subproc = spawn('myex.',['param1', 'param2'], {
detached: true,
stdio: 'ignore'
});
subproc.unref();
});
The problem is that when node.js tries to launch the executable in a new process, an exeption arises:
Error: spawn EBUSY
I tried to execute in the same way the .exe file without downloading it and the process is correctly created. If I execute it with the exec function it works perfectly but I cannot detach the new process. What is the problem and what could be a possible solution?
i think the problem is file is occupied, my way is , use settimeout ,wait for a while , and then use execFile

Receiving "error: no such file or directory, open" when passing a remote file to libreoffice-convert library in a Node.js app

I'm currently building a Node.js application that will eventually be used to convert certain file formats into other formats. Most of the work is being done by the libreoffice-convert library.
I am able to do file conversions without any issues when passing a local file path to the library but it doesn't seem to be working when I grab the contents of a remote file via request() and pass the received body to libreoffice-convert.
This is the relevant code I have right now:
request(fileUrl, {encoding: 'binary'}, function(error, response, body) {
const ext = '.html';
libre.convert(body, ext, undefined, (err, done) => {
if (err) {
console.log(`Error converting file: ${err}`);
res.sendStatus(500);
} else {
console.log(done);
}
});
});
I can see that when I run this, libreoffice starts the conversion but eventually, I'm getting this error:
Error: ENOENT: no such file or directory, open '/var/folders/j9/z_z85kh5501dbslrg53mpjsw0000gn/T/libreofficeConvert_-6529-x08o2o3peLMh/source..html
The example libreoffice-convert code gets the local file using fs.readFileSync() but given that I want to get my contents from a remote file, I'm passing the body received in the request() call.
To be sure that body has the correct contents, I compared the result I receive from fs.readFileSync() to the result I receive from request() when calling for the same exact file locally and remotely. There didn't seem to be any differences at all.
Am I missing something or it's a matter that the libreoffice-convert library or libreoffice itself doesn't support this?
libreoffice-convert is dependent on some linux package, i.e. libreoffice-writer. apt install libreoffice-writer will solve your problem.

My cli engine(npm package) cant find path to read file when install on another folder

I am building an app that auto completes some type of file. When i run node index.js in the program folder i get the correct i results.
Although i want to make it an npm package that can work as a cli engine. For example i want to write the command generate and the code to produce the results.
In order to auto complete the file i have to read some data that i have stored in a .csv file that comes along with my program.
When i try to run generate command under another folder it can read that file.
I am very new to cli and i don't understand yet quite well how thing work.
Thanks in advance for the help.
Here is the code of my cli conversion.
#!/usr/bin/env node
const program = require("commander");
const {
predict
} = require("./classifier");
program.version("1.0.0").description("ESLint Rules Generator");
program
.command("generate")
.description("Generate ESLint Rules")
.action(() => {
predict();
});
program.parse(process.argv);
Here is the problematic line:
let str = fs.readFileSync("data_files/rules.csv", "utf-8");
This is the error i get: ENOENT: no such file or directory, open 'data_files/rules.csv'

Copy contents of image file to the clipboard using gulp

I'm writing a gulp task to do the following:
Watch an image file for changes
If image file has changed, copy the contents of the image to the clipboard, ready for me to paste.
Note: I'm on Windows and am using nircmd.exe to do the copy of the image contents. The following command line works for me:
nircmd.exe clipboard copyimage "G:\IMG\pic.png"
I've put this into a .bat file so I can run the file via commandline.
My gulpfile (so far):
var gulp = require('gulp'),
watch = require('gulp-watch'),
shell = require('gulp-shell'),
run = require('gulp-run'),
clipboard = require("gulp-clipboard"),
myTerminal = require("child_process").exec,
commandToBeExecuted = "./copy-to-clipboard.bat";
gulp.task('copy-to-clipboard', function () {
require('child_process').spawn('cmd', ['/s', '/c', '"G:\\Git\\copy-to-clipboard\\copy-to-clipboard.bat"'], {
windowsVerbatimArguments: true
});
});
gulp.task('default', function () {
watch('watch/*.png','copy-to-clipboard');
});
I've tried gulp-shell but since this opens a node terminal, nircmd.exe is not recognised as an internal or external command.
I've also tried child_process (both spawn and exec), but while I get no errors, the contents are still not in the clipboard.
Is there an easier way or is this just not possible?
Thanks in advance!
It sounds like its trying to run it if you are getting a
nircmd.exe is not recognised as an internal or external command.
error.
I would add nircmd.exe to your path to fix it.
or in your bat file you could do something like:
c:\path\to\program\nircmd.exe
that might fix it to.
If you are going to use nircmd that much I would just add it to your path.

Resources