Get full path of a directory in node webkit - javascript

How can I get the absolute path of a directory (not the current working directory) in node webkit application?
Example (Mac OS) - I have created a folder named A in my Documents. When I do getDirectory with file system directory entry, I can only get dir.fullPath which returns A
app.workspace.getDirectory(self.folderpath, {}, function(dir){
if(dir) console.log('Dir: ', dir);
});
But I need: ~/Documents/A/ || c:\Users\Username\Documents
In my app users can choose/create a directory where ever they want and I store/read data from that folder.
Absolute path may not be what I need but I want to open files (PDF, doc...) with default desktop applications:
function getCommandLine() {
switch (process.platform) {
case 'darwin' : return 'open';
case 'win32' : return 'start';
case 'win64' : return 'start';
default : return 'xdg-open';
}
}
var exec = require('child_process').exec;
var filepath = '...';
//dir.fullPath will throw: The file /A/example.pdf does not exist.
var child = exec(getCommandLine() + ' ' + filepath, function (error, stdout, stderr) {
if (error) {
console.error(`exec error: ${error}`);
return;
}
});
child.on('close', function (e) {
console.log('E: ', e);
});

You cannot access the absolute path of a system's directory-file-everything from a web page for security reasons. Even if you try to access a specific file directory from a javascript script (for example), the browser will immediately block you.
A solution that might work for you is to retrieve the file that the user wants to open with a simple <input type="file">, so that the user can select a file without giving to you its absolute path;after that you can save the file onto a server-host, or even the project's local directory, and then use the remote path to open it with the exec command.

Not sure I've understood thequestion. You can user __dirname to get the directory of the script you are executing. See: https://nodejs.org/docs/latest/api/globals.html#globals_dirname
And from there you can use relative paths to reference other files and folders.
Example folder structure:
/home/filippo/works/test/
├── subfolder
│   └── index.js
└── test.js
subfolder/index.js:
module.exports = {'folder': __dirname};
test.js:
var m = require("./subfolder/");
console.log("test.js running in: ", __dirname);
console.log("m module running in: ", m.folder);
Running the test:
$ node test.js
test.js running in: /home/filippo/works/test
m module running in: /home/filippo/works/test/subfolder
Is this what you are looking for?

Actually I recently found out (I can't believe I missed it out in the first place but), with chrome file system you can get "more readable" path info for display purposes.
Depending on what you are trying to do, you might not access the absolute location but at least you can see what it is...
fileSystem.getDirectory(path, {}, function(dir){
if(dir) console.log('This should return full path: ', dir.getDisplayPath());
var fullpath = dir.getDisplayPath();
//now with this, I can open any file I want via child process :)
var child = exec(getCommandLine() + ' ' + fullpath, function (error, stdout, stderr)
//.......
});
More info here regarding chrome file system.

Related

Arguments for Node child_process "spawn()"

Using child_process (spawn) to open a new BASH terminal and execute the commands in each file.
I want to add all of my .sh files, that I'm going to spawn, into a folder to clean up my project directory.
PROBLEM:
I can't figure out how to change the directory the scripts run from, and the docs are a little to heavy for me at this point.
SIMPLE TEST EXAMPLE, WITH MY FIRST TWO FILES FOR CONNECTING (each .sh file would be in the project folder):
const { spawn } = require('node:child_process');
const bat = spawn('cmd.exe', ['/c', 'connect.sh']);
/*
<connect.sh> // 1st .sh file
#!/usr/bin/env bash //to make it bash
HTTP_PORT=3002 P2P_PORT=5002 PEERS=ws://localhost:5001 npm run dev
<connect1.sh> // 2nd .sh file
#!/usr/bin/env bash //to make it bash
HTTP_PORT=3003 P2P_PORT=5003 PEERS=ws://localhost:5002,ws://localhost:5001 npm run dev
*/
I have 9 of these files to connect up to 10 peers. And I would like to put them in a folder to simplify my project structure.
This is my actual API call below....
// Uses length to determine which file to run
app.post("/peers/connect", async function (req, res) {
const peerInfo = await peers.info();
// no peers yet
if (typeof peerInfo === "string") {
let bat = spawn("cmd.exe", ["/c", "connect.sh"]);
res.json("A new terminal has opened! You are now connected!");
} else {
// peers exist
let length = peerInfo.peers;
// console.log(length);
let bat = spawn("cmd.exe", ["/c", `connect${length}.sh`]);
res.json("A new terminal has opened! You are now connected!");
}
});
My file structure here...you can see why I want a folder for these!
RECAP:
Help my put all of these files into a folder (shellScripts) and have the code still work :)
Thanks! (just realized we might have to cd back into project folder before "npm run dev" in each file?)
You are using the cmd.exe utility to run a .sh file, but that wont work. You have to install a bash interpreter on your windows device or install WSL. (If necessary add bash.exe to the windows path) Then change your code to this:
const { spawn } = require('node:child_process');
const bat = spawn('bash.exe',['connect.sh']);
I hope this answer helped
For running multiple files:
const { spawn } = require('node:child_process');
const fs = require("node:fs")
const dir = "" // Replace this with the location of the directory containing connect shellscripts
let entrys = fs.readdirSync(dir)
entrys = entrys.filter(v => v.startsWith("connect"))
for (let ent of entrys) {
const bat = spawn('bash.exe',[ent]);
// your code here
}
Figured out the answer on me own. Thanks to everyone that tried to help :)
And to those saying my above code doesn't work, it works perfectly fine.
I've provided a picture to clarify. 1st is what the code below produces. 2nd is manually pasting it into GIT BASH.
// test.js in project structure pic above
var exec = require('child_process').exec;
var path = require('path')
var parentDir = path.resolve(process.cwd(), 'shellScripts');
exec('my.sh', {cwd: parentDir}, function (error, stdout, stderr) {
// if you also want to change current process working directory:
process.chdir(parentDir);
});
This is what the code produces.
And this is opening a GIT BASH in project folder and pasting the command in

Get javascript filepath in Windows Script Host

When using .js files that are run with Windows Script Host, is it possible to get the path of the .js file that is running (which is not the same as the current working directory)? In other words, I'm wanting something similar to PowerShell's $PSScriptRoot variable. Is there any way to get this?
The reason I want this is because the working directory when these scripts are executed is not always the same as the location of the .js file itself, but I want my code to reference things relative to the location of the .js file.
You can get this with Node Js
const path = require('path'); // you can install this with npm
// __dirname = C:\dev\project
// __filename = C:\dev\project\index.js
const dir= path.basename(__dirname);
const archive= path.basename(__filename);
const fullpath = path.join(dir, archive);
console.log('Dir:', dir); // Dir: test
console.log('Archive:', archive); // Archive: index.js
console.log('Dir + Archive:', fullpath); // Dir + Archive: project\index.js

Using Javascript as hook for cordova project in Visual Studio 2017

I'm having a cordova project running in Visual Studio. Before the build process I want to use the hook functionality in order to copy an additional gradle file to the corresponding platforms folder. For copying this file I'm using a simple javascript file. I want to use js because it is independent of the OS.
I use the following code from here:
source = "D:\\myProject\\config\\build-extras.gradle";
target = "D:\\myProject\\platforms\\android\\build-extras.gradle";
var fs = require('fs');
var cbCalled = false;
var rd = fs.createReadStream(source);
rd.on("error", function(err) {
done(err);
});
var wr = fs.createWriteStream(target);
wr.on("error", function(err) {
done(err);
});
wr.on("close", function(ex) {
done();
});
rd.pipe(wr);
function done(err) {
if (!cbCalled) {
console.log("Something wrong with copy of build-extras.gradle: " + err);
cbCalled = true;
}
}
When I run this code in a console with node, then the script is copying the file as expected.
However, when I include the same script in my config.xml file of cordova the script is doing something different: It creates a file with the defined name but the file is always empty.
Does anybody know what's wrong here?
Thanks, Peter

list all the files with the same extension as specified by the user

prints a list of files in a given directory, filtered by the extension of the files. The first argument will be the path to the directory we want to filter on, and the second argument, the type of the file that we need to print,
we must use readdir function .
like running this:
node fileJS.js /Users/admin/Desktop .docx
I've tried this code, but it will no return anything, for some reason.
can you please help me
var fs = require('fs'); //require node filesystem module
var path = require('path'); //require node path module (a couple of tools for reading path names)
var pathSupplied = process.argv[2];
var extFilter = process.argv[3];
function extension(element) {
var extName = path.extname(element);
return extName === '.' + extFilter;
};
fs.readdir(pathSupplied, function(err, list) {
list.filter(extension).forEach(function(value) {
console.log(value);
});
});
The problem is when you provide the extension argument starting with a . because in your filter function (extension) you are adding another dot when comparing (line: return extName === '.' + extFilter;).
Just invoke your current script like this:
node fileJS.js /Users/admin/Desktop docx
Or update your filter function to assume extFilter is provided with a starting dot.
Invoke the command like this:
node fileJS.js /Users/admin/Desktop docx
...without the dot in front of the extension you're looking for. Your code works then, I just tested it.

Use node.js to save json file

I am very new to Node server/javacsript. So I am sorry if this might be stupid
question/topic.
I intended to create a very simple solution to open JSON file, load to list, and save it back to my local disk (running node.js server).
Could you please help me out, what I am doing wrong? I am running app in browser using react.
index.js containing
var fs = require('fs');
var fileName = './test.json';
var file = require('./test.json');
alert(file.name + " " + file.age);
file.name = "Peter";
alert(file.name + " " + file.age);
fs.writeFile('./test.json', JSON.stringify(file), function (err) {
if (err) return alert(err);
console.log(JSON.stringify(file));
alert('writing to ' + fileName);
});
Before I was not even able to open JSON file. I needed to include this property into the webpack config file.
node: {
fs: 'empty'
}
Now I am able to open JSON file, change it virtually, but unable to save it.
In chrome developer tools, it prints "fs.writeFile is not a function" into console.
Thank you very much.
When you included the property in your webpack config
node: {
fs: 'empty'
}
You told webpack that the module fs should just be an empty object. You can confirm this by simply putting a console.log(fs) in your file to see it is indeed empty.
Beyond that, fs is not going to work in your browser. fs expects the node.js runtime (which includes non-JavaScript things in order to make it work), not your browser's runtime.
If you want a user to save a file, you'll have to use a browser based saving solution. You won't be able to just arbitrarily write files like that outside of something like your browser's local storage.

Categories

Resources