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
Related
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
I am having JavaScript file under menu directory in the root menu.js. I want to rename JavaScript file menu.js to menuOLD.js under same directory onClick.
I would have googled and found small sample as :
function renamefile(){
const myFile = new File(['hello-world'], 'my-file.txt');
const myRenamedFile = new File([myFile], 'my-file-final-1-really.txt');
console.log(myRenamedFile);
}
I have checked it's output in Console and got below output:
It's working.
But I would need to rename excatly menu.js file under menu directory.
How should I do this?
With Node.js
const fs = require('fs');
fs.rename('menu.js', 'menuOLD.js', (err) => {
console.log(err);
});
See here:
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.
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.
I have a file named test.apk this file in located in C:\\workspace\app\build\output\apk\test.apk
in node js i tried following code
var workDir = 'C:\\workspace\app'
var path = require('path');
var localTagPath = path.dirname(workDir);
console.log(path.resolve(localTagPath, 'test.apk'))
what i need is to get the test.apk without specifyinh the path in code
(var workDir = 'C:\\workspace\app\build\output\apk\test.apk')
instead of this ihave to specify like this
where local path is
var localpath = workDir +(\..+\..+\..\)+test.apk
path.resolve(localTagPath, 'test.apk')
You cannot use local file paths as browsers do not have access to the computer's filesystem.