fs.stat函数,用于在Windows中指向目录的符号链接

时间:2018-09-17 06:32:56

标签: javascript node.js windows appveyor

在我的Windows环境(x64)中,fs.stat的指向目录的symlink函数带来了错误。

另一方面,在传送带(ia32)中,fs.stat的{​​{1}}函数指向目录很好用。

这是为什么?哪种行为是正确的?

我的测试代码的一部分是

symlink

有关所有代码,请参见https://github.com/knight9999/WindowsSymbolicLinkCheck

在我本地环境中的结果是

it('Test 001 : fs.stat for symlink', function () {
  var target = path.resolve(workDir, 'sample1');
  console.log('target :' + target);
  fs.mkdirSync(target);                 // create directory
  var link = path.resolve(workDir, 'link1');
  console.log('link :' + link);
  fs.symlinkSync(target, link);         // create symlink to directory

  expect(function() {
    var stat = fs.statSync(link);       // checking symlink stat
    console.log(stat);
  }).not.toThrow();

});

Appveyor中的结果是

Failures:
1) win symlink tests Test 001 : fs.stat for symlink
  Message:
    Expected function not to throw, but it threw Error: EPERM: operation not permitted, stat 'C:\Users\knaito\AppData\Local\Temp\appveyor-tests-winSymlinkTests-VcfaRo\link1'.
  Stack:
    Error: Expected function not to throw, but it threw Error: EPERM: operation not permitted, stat 'C:\Users\knaito\AppData\Local\Temp\appveyor-tests-winSymlinkTests-VcfaRo\link1'.
        at <Jasmine>
        at UserContext.<anonymous> (C:\Users\knaito\Documents\work\cordova-develop\WindowsSymbolicLinkCheck\spec\winSymlink.spec.js:24:12)
        at <Jasmine>

1 spec, 1 failure

请参阅https://ci.appveyor.com/project/knight9999/windowssymboliclinkcheck

注意: 我知道Started target :C:\Users\appveyor\AppData\Local\Temp\1\appveyor-tests-winSymlinkTests-NsaPyJ\sample1 link :C:\Users\appveyor\AppData\Local\Temp\1\appveyor-tests-winSymlinkTests-NsaPyJ\link1 Stats { dev: 3567992900, mode: 16822, nlink: 1, uid: 0, gid: 0, rdev: 0, blksize: undefined, ino: 844424934502125, size: 0, blocks: undefined, atimeMs: 1537164694047.7703, mtimeMs: 1537164694047.7703, ctimeMs: 1537164694047.7703, birthtimeMs: 1537164694047.7703, atime: 2018-09-17T06:11:34.048Z, mtime: 2018-09-17T06:11:34.048Z, ctime: 2018-09-17T06:11:34.048Z, birthtime: 2018-09-17T06:11:34.048Z } . symlinkd适用于Windows中的目录。 但是,对于指向目录的junction的{​​{1}}会自动创建新的fs.copyjunctionsymlink都不自动)。

2 个答案:

答案 0 :(得分:0)

我自己详细发现了这个问题。

对于Windows 10,fs.statSync调用nodejs内部函数

INLINE static void fs__stat_impl(uv_fs_t* req, int do_lstat) {
  HANDLE handle;
  DWORD flags;

  flags = FILE_FLAG_BACKUP_SEMANTICS;
  if (do_lstat) {
    flags |= FILE_FLAG_OPEN_REPARSE_POINT;
  }

  handle = CreateFileW(req->file.pathw,
                       FILE_READ_ATTRIBUTES,
                       FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                       NULL,
                       OPEN_EXISTING,
                       flags,
                       NULL);
  if (handle == INVALID_HANDLE_VALUE) {
    SET_REQ_WIN32_ERROR(req, GetLastError());
    return;
  }
  ...
deps/uv/src/win/fs.c

。 参见https://github.com/nodejs/node/blob/9b292272ff3d71a0ebabe46d040346dbd34585db/deps/uv/src/win/fs.c#L1252

CreateFileW返回INVALID_HANDLE_VALUE,指向指向其他目录的symlink

但是对于Windows Server 2012 R2(与appveyor中相同),此功能运行良好。

因此

node -e "console.log(fs.statSync('/path/to/symlink/pointing/other/directory`));"

在Windows 10上出现错误,在Windows Server 2012 R2上效果很好。

我得出结论,我们应该避免使用symlink指向Windows 10中的其他目录。junction更好。

答案 1 :(得分:0)

如果执行文件位于ex:src / webpack /文件夹内,然后将其移至src /,然后在package.json中的脚本中执行命令,则它将起作用。