I'm working on a project in node js and I need to get the file system type of a disk i.e., I want to know if it's FAT or NTFS etc...
Is there any way I can accomplish this with node js? Any help is appreciated . Thanks.
As you didn't specify target machine's operating system, you can use such command under Windows:
fsutil fsinfo volumeinfo <disk letter here>:
to show output simillar to this one:
H:\>fsutil fsinfo volumeinfo c:
Volume Name :
Volume Serial Number : 0x4c31bcb3
Max Component Length : 255
File System Name : NTFS
Supports Case-sensitive filenames
Preserves Case of filenames
Supports Unicode in filenames
Preserves & Enforces ACL's
Supports file-based Compression
Supports Disk Quotas
Supports Sparse files
Supports Reparse Points
Supports Object Identifiers
Supports Encrypted File System
Supports Named Streams
You need only to parse command output correctly. I would recommend you storing filesystem names in array and seeking for every in command output excluding first line. This way you can be sure which filesystem is used by target machine.
Here you have code to print what does this command output to your commandline:
const { exec } = require('child_process');
exec('fsutil fsinfo volumeinfo c:', (err, stdout, stderr) => {
if (err) {
// node couldn't execute the command
return;
}
// the *entire* stdout and stderr (buffered)
console.log(`stdout: ${stdout}`);
});
This is untested code, I really think that you want to write own snippet. I can't decide will this code work because I have no opportunity now.
Also, why would you check filesystem used?
you can use github.com/resin-io-modules/drivelist
then
const drivelist = require('drivelist');
drivelist.list((error, drives) => {
if (error) {
throw error;
}
console.log(drives);
});
Related
I am writing an extension for vscode, and I need to get the environment variables of a process that is already running. But I wasn't able to find a way to do it.
I know how to do it in python using psutil:
for proc in psutil.process_iter(attrs=['name', 'exe']):
if proc.info['name'].lower() == 'SomeProcess.exe'.lower():
return proc.environ()
Is there something similar for javascript/nodejs?
You can use child_process module to spawn a terminal and execute the following commands wrt platform and get the variables, parse & use or write a native node module to access the proper APIs of each platform and get the output.
Windows (Using powershell, 2019 is the PID )
(Get-Process -id 2019).StartInfo.EnvironmentVariables
Linux
tr '\0' '\n' < /proc/2019/environ
Mac
ps eww -o command 2019 | tr ' ' '\n'
Thanks to https://serverfault.com/a/66366 & https://stackoverflow.com/a/28193753/12167785 & https://apple.stackexchange.com/a/254253 &
https://stackoverflow.com/a/11547409/12167785 &
https://stackoverflow.com/a/18765553/12167785
Combining with #SudhakarRS's answer:
var child = require('child_process').execFile('powershell', [
'(Get-Process SomeProcess).StartInfo.EnvironmentVariables'
], function(err, stdout, stderr) {
console.log(stdout);
});
If you want to debug it, make sure you peek at err and stderr.
Replacing SomeProcess with notepad works for me, but using notepad.exe does not.
On powershell you can get the processes with a particular name using Get-Process [process name].
So, for example, if I have 4 instances of notepad running and do Get-Process notepad, I see this:
You can get the process IDs with (Get-Process notepad).Id which returns:
You could use the same code to choose the ID:
var child = require('child_process').execFile(
'powershell',
['(Get-Process notepad).Id'],
function(err, stdout, stderr) {
var ids = stdout.split("\r\n");
ids.pop(); //remove the blank string at the end
console.log(ids);
}
);
^ which returns:
If you just want to grab the first process with a name, it's:
(Get-Process notepad)[0].StartInfo.EnvironmentVariables
^ obviously replace notepad with your process name.
Easyish way(from here, you can use something like shelljs then run:
ps faux | grep 'PROCESS_NAME'
Then extract the process id(I'm just working on a regex) and then do:
cat /proc/THE_PROCESS/environ | tr '\0' '\n'
You'll get the the env vars back as a string something like:
THEVAR=1
ANOTHERVAR=2
I reckon you just split the string by '\n' but I'm checking!
I'll update this once I figure the regex. **Are you on linux/mac or windows?
UPDATE: Check https://github.com/shelljs/shx for cross platform
There is no builtin way to do that in javascript/nodejs. If you really need to do it, then the best way is to run a command in the terminal and then parse the output to construct the object that you need.
yep:
process.env will give you what you need :)
you can read some more here.
EDIT: it will give you environment variables only for the process you're in... did I misunderstood and you want varibales of another process?
This node code snippet returns different values based on the node platform version. I have two identical instances (except for the node version) in EC2 running Ubuntu 14.04.
"use strict";
var crypto = require("crypto");
crypto.pbkdf2("password", "salt", 1000, 32, function(err, derivedKey) {
if (err) {
console.error(err);
} else {
console.log(new Buffer(derivedKey).toString('base64'));
}
});
On node v0.8.28 the console value is:
bsKIwr7Ci8KtfsKuwp3CnhDCqgYSJANPw61Iw5A/w4vCrcKWwotWAGfChFPCnVIU
On node v0.10.5 the value is:
boi+i61+rp2eEKoGEiQDT+1I0D/LrZaLVgBnhFOdUhQ=
This is a huge problem since we are upgrading the node version on the app and passwords cannot be decrypted properly.
Thanks!
It's strange how you find answers after you ask for help.
By passing the encoding type to the Buffer function like this:
console.log(new Buffer(derivedKey,'binary').toString('base64'));
...I can get the same hash.
It turns out the default type was changed from binary to utf8, so 'binary' needs to be specified now.
https://nodejs.org/api/crypto.html#crypto_crypto_pbkdf2_password_salt_iterations_keylen_digest_callback (see bottom notes)
How can I tell if a file-system path is a hard link with Node.js? The function fs.lstat gives a stats object that, when given a hard link will return true for stats.isDirectory() and stats.isFile() respectively. fs.lstat doesn't offer up anything to note the difference between a normal file or directory and a linked one.
If my understanding of how linking (ln) works is correct, then a linked file points to the same place on the disk as the original file. This would mean that both the original and linked version are identical, and there is no way to tell the difference between the original file and the linked.
The functionality I'm looking for is as follows:
This is hypothetical pseudo-code for demonstration & communication purposes.
fs.writeFileSync('./file.txt', 'hello world')
fs.linkSync('./file.txt', './link.txt')
fs.isLinkSync('./file.txt') // => false
fs.isLinkSync('./link.txt') // => true
fs.linkChildrenSync('./file.txt') // => ['./link.txt']
fs.linkChildrenSync('./link.txt') // => []
fs.linkParentSync('./link.txt') // => './file.txt'
fs.linkParentSync('./file.txt') // => null
Alright.. just for fun...
You may have an option for finding the files via inode in a certain directory.
Once you grab the inode ID from the stat object..
fs.stat('./okay.file', function(err, stats){
var inodeID = stats.ino; // Double check that this is correct
});
You can then iterate over all the files in the folder and check with a conditional if the inode ID matches. Get all files in a directory. If it doesn't, you can assume there is no link (IN that current directory).
However, it doesn't look like we could search for a file by the inode id. see: nodejs open nfs files by inode (or a the fastest way to reopen a file)
fs.lstat: https://nodejs.org/api/fs.html#fs_fs_lstat_path_callback
Stats object: https://nodejs.org/api/fs.html#fs_class_fs_stats
Sorry but that is not possible you can't differ between original and hard linked file. They are the same on your linux system and poinzing to the same inode.
My requirement is I need to check whether Chrome browser is insatlled on the client machine or not using Javascript. I have searched on the net not able to find the way out.
Please help in getting this done.
You can't do that with JavaScript, and even if you could, you shouldn't.
JavaScript on the client doesn't have access to the user's system, for very good reasons. (Think, servers with bad intentions.)
You can check if the browser is Chrome with the next code
if(!window.chrome){
//Chrome code
}else{
// Chrome block
}
You can't. Not with JavaScript. However, you can check whether the browser that is currently being used to view your webpage is Google Chrome or not.
<script type="text/javascript">
if(window.chrome){
document.write("Browser is Chrome");
}
else{
document.write("Please download Chrome");
}
</script>
You can't get that kind of information directly from javascript.
What you can do is use that PowerShell command in a script and save the result in a file that you'll read later using javascript.
Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | Select-Object DisplayName, DisplayVersion, InstallLocation, Publisher, InstallDate | Format-Table -AutoSize
This will get you all the installed programs on the machine from the HKEY_LOCAL_MACHINE registry folder.
The exact path to the folder from wich the informations are retrieved is : HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\
The given command will display you the application name followed by it's version, it's install location, publisher name and installation date in a PowerShell terminal.
If you want to output that list in a file simply add >FileName.txt after the command before pressing enter.
Note that by default the file will be created in the C:\Users\YourUserName\ folder so if you want the file to be created in a specific location you'll have to use the CD command to get to that specific location before executing the Get-Item-Property command.
This will get you done for the get installed programs on a machine part.
Now we can get into the check if app x is installed on the machine part.
First load the previously generated file in your js application you will use it's content to determine if an application is installed on the computer.
The faster way to get if 'chrome' is installed will be to load the file as a string and then do that basic stuff :
if (string.includes('chrome') == true) {
// chrome is installed on the machine
// you can do some more stuff
// like extracting it's path from the file content
} else {
console.log('error: chrome is not installed on this computer');
}
Needless to say that this will only work if used on the same computer from which you want to check the installed applications.
Edit: If you want a more practical file to use in javascript you can replace
Format-Table -AutoSize >FileName.txt
with :
Export-Csv -path .\FileName.txt -NoTypeInformation
this way you can split your file lines using the string.split(',') method and don't have to do some extra stuff to deal with the spaces between data.
Edit 2:
Here's a full working implementation that will let you retrieve informations from a PowerShell script directly from your javascript using NodeJs.
get_programs.ps1 (PowerShell script file) :
chcp 65001 # sets the encoding for displaying chars correctly
Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | Select-Object DisplayName, DisplayVersion, InstallLocation | ConvertTo-Csv -NoTypeInformation
chcp 850 # restores the default encoding set this will avoid police changes due to the terminal modifications
Notice the change at the end of the command which is now:
| ConvertTo-Csv -NoTypeInformation
this allows to log data in the PowerShell terminal in the csv format which will simplify it's parsing as a string.
If you don't want to use another file to hold those few PowerShell
commands you can use this
child = spawn("powershell.exe",[`chcp 65001
Get-ItemProperty HKLM:\\Software\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\* | Select-Object DisplayName, DisplayVersion, InstallLocation | ConvertTo-Csv -NoTypeInformation
chcp 850`]);
as a replacement for
child = spawn("powershell.exe",["./get_programs.ps1"]);
If you choose to do this don't forget to escape the \ chars else it will not work.
app.js :
var spawn = require("child_process").spawn,child;
child = spawn("powershell.exe",["./get_programs.ps1"]); // here we start our PowerShell script "./" means that it's in the same directory as the .js file
let chromeDetails;
child.stdout.on("data", (data) => { // data event
// here we receive each outputed line in the PowerShell terminal as an Uint8Array
if (data.includes('Chrome')) { // check for the 'Chrome' string in data
chromeDetails = data.toString(); // adds data converted as string
}
});
child.stderr.on("data", (data) => { // logs errors
console.log(`Powershell Errors: ${data}`);
});
child.on("exit", () => { // exit event
console.log("Powershell Script finished");
if (chromeDetails != undefined) {
console.log(`> chrome has been detected on this computer
available informations (appName, version, installPath):
${chromeDetails}`);
} else
console.log('> chrome has not been detected on this computer');
});
child.stdin.end(); // we end the child
Expected output :
Powershell Script finished
> chrome has been detected on this computer
available informations (appName, version, installPath):
"Google Chrome","103.0.5060.114","C:\Program Files\Google\Chrome\Application"
If you are not on Windows you may want to take a look at Spawning .bat and .cmd files on Windows from the NodeJs documentation to get hints on how to adapt the above app.js code to work on your system.
I'm trying to write a function, that would use native openssl to do some RSA heavy-lifting for me, rather than using a js RSA library. The target is to
Read binary data from a file
Do some processing in the node process, using JS, resulting in a Buffer containing binary data
Write the buffer to the stdin stream of the exec command
RSA encrypt/decrypt the data and write it to the stdout stream
Get the input data back to a Buffer in the JS-process for further processing
The child process module in Node has an exec command, but I fail to see how I can pipe the input to the process and pipe it back to my process. Basically I'd like to execute the following type of command, but without having to rely on writing things to files (didn't check the exact syntax of openssl)
cat the_binary_file.data | openssl -encrypt -inkey key_file.pem -certin > the_output_stream
I could do this by writing a temp file, but I'd like to avoid it, if possible. Spawning a child process allows me access to stdin/out but haven't found this functionality for exec.
Is there a clean way to do this in the way I drafted here? Is there some alternative way of using openssl for this, e.g. some native bindings for openssl lib, that would allow me to do this without relying on the command line?
You've mentioned spawn but seem to think you can't use it. Possibly showing my ignorance here, but it seems like it should be just what you're looking for: Launch openssl via spawn, then write to child.stdin and read from child.stdout. Something very roughly like this completely untested code:
var util = require('util'),
spawn = require('child_process').spawn;
function sslencrypt(buffer_to_encrypt, callback) {
var ssl = spawn('openssl', ['-encrypt', '-inkey', ',key_file.pem', '-certin']),
result = new Buffer(SOME_APPROPRIATE_SIZE),
resultSize = 0;
ssl.stdout.on('data', function (data) {
// Save up the result (or perhaps just call the callback repeatedly
// with it as it comes, whatever)
if (data.length + resultSize > result.length) {
// Too much data, our SOME_APPROPRIATE_SIZE above wasn't big enough
}
else {
// Append to our buffer
resultSize += data.length;
data.copy(result);
}
});
ssl.stderr.on('data', function (data) {
// Handle error output
});
ssl.on('exit', function (code) {
// Done, trigger your callback (perhaps check `code` here)
callback(result, resultSize);
});
// Write the buffer
ssl.stdin.write(buffer_to_encrypt);
}
You should be able to set encoding to binary when you make a call to exec, like..
exec("openssl output_something_in_binary", {encoding: 'binary'}, function(err, out, err) {
//do something with out - which is in the binary format
});
If you want to write out the content of "out" in binary, make sure to set the encoding to binary again, like..
fs.writeFile("out.bin", out, {encoding: 'binary'});
I hope this helps!