Because node.js doesn't offer a way to retrieve and modify the file attributes on windows I need to execute a child process. I want to get all the file attributes, that is:
- size
- archive
- hidden
- readonly
- system
- creation/modified/access time
- file?/directory?/symlink? (junction)
If I'm going to execute a child process I don't want to call to fs.stat because it's an extra I/O access (and Stats doesn't offer too many information on windows). If I execute a child process I want to retrieve all the data at once.
So, I've written a powershell script:
var cmd = "powershell -Command \"$item=get-item a -force;[bool]($item.attributes -band [io.fileattributes]::directory);[bool]($item.attributes -band [io.fileattributes]::archive);[bool]($item.attributes -band [io.fileattributes]::reparsepoint);[bool]($item.attributes -band [io.fileattributes]::hidden);[bool]($item.attributes -band [io.fileattributes]::readonly);[bool]($item.attributes -band [io.fileattributes]::system);$item.length;$tmp=$item.creationtime;$tmp.year;$tmp.month;$tmp.day;$tmp.hour;$tmp.minute;$tmp.second;$tmp.millisecond;$tmp=$item.lastaccesstime;$tmp.year;$tmp.month;$tmp.day;$tmp.hour;$tmp.minute;$tmp.second;$tmp.millisecond;$tmp=$item.lastwritetime;$tmp.year;$tmp.month;$tmp.day;$tmp.hour;$tmp.minute;$tmp.second;$tmp.millisecond;$s\"";
This returns: (once has been splitted in javascript: split("\r\n")
)
[ 'False', //directory?
'True', //archive?
'False', //symlink?
'False', //hidden
'False', //readonly?
'False', //system?
'3', //length (if directory, empty string)
'2012', //creation time, year
'11', //creation time, month
'18', //creation time, day
'6', //creation time, hour
'8', //creation time, min
'44', //creation time, ysec
'457', //creation time, millis
'2012', //last access time, year...
'11',
'18',
'6',
'8',
'44',
'457',
'2012', //last modified time, year...
'11',
'18',
'14',
'0',
'38',
'859',
'' ]
The problem is that windows XP doesn't come with powershell and you need to install it (btw who's using windows xp with node.js nowadays? silly), so I'm searching a cmd command that can retrieve the same information. I've seen that dir
can show all I need but it doesn't show seconds and milliseconds and I've not found a way to determine if a file is a symlink...
EDIT: The solution seems to be in Windows Script Host. Available since windows 98 and the scripts are written in javascript.
SOLUTION:
Windows Host Script in jscript:
whs.js
var fs = new ActiveXObject ("Scripting.FileSystemObject");
var name = WScript.Arguments.item (0);
var file;
try{
file = fs.getFile (name);
}catch (e){
file = fs.getFolder (name);
}
//http://msdn.microsoft.com/en-us/library/windows/desktop/gg258117%28v=vs.85%29
//-1 if true, 0 if false
WScript.echo (!!(file.attributes & 1)); //Read-only
WScript.echo (!!(file.attributes & 2)); //Hidden
WScript.echo (!!(file.attributes & 4)); //System
WScript.echo (!!(file.attributes & 16)); //Directory
WScript.echo (!!(file.attributes & 32)); //Archive
WScript.echo (!!(file.attributes & 1024)); //Reparse point (symbolic link)
WScript.echo (file.size); //0 if directory
WScript.echo (file.dateCreated);
WScript.echo (file.dateLastAccessed);
WScript.echo (file.dateLastModified);
Node.js:
var file = "a";
require ("child_process").exec ("cscript " + __dirname +
"/wsh.js " + file + " //Nologo",
function (error, stdout, stderr){
if (error) return console.log (error);
if (stderr) return console.log (stderr);
stdout = stdout.split ("\r\n");
console.log(stdout)
});
Result:
[ '0',
'0',
'0',
'0',
'-1',
'0',
'3',
'18/11/2012 15:45:04',
'18/11/2012 15:45:04',
'18/11/2012 15:45:12',
'' ]
Milliseconds cannot be retrieved but it's ok (linux atime, mtime don't have ms)