Retrieve file attributes from windows cmd

2019-02-22 09:53发布

问题:

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)

回答1:

You already answered yourself.But there's a way to read some file attributes with a batch file :

c:\>for /f %A in ("example.file") do echo %~aA

of in a batch script:

for /f %%A in ("example.file") do echo %%~aA

or with ATTRIB:

c:\>attrib + semitest.bat /s /d

where the atributes are:

    R  Read-only (1)
    H  Hidden (2)
    A  Archive (32)
    S  System (4)

extended attributes:

    E  Encrypted
    C  Compressed (128:read-only)
    I  Not content-indexed
    L  Symbolic link/Junction (64:read-only)
    N  Normal (0: cannot be used for file selection)
    O  Offline
    P  Sparse file
    T  Temporary