我需要访问在Windows上运行的Node应用程序中的每台计算机配置数据。我找到了关于如何找到位置的文档:
Where Should I Store my Data and Configuration Files if I Target Multiple OS Versions?
所以,就我而言,我想获得CSIDL_COMMON_APPDATA
(或FOLDERID_ProgramData
)的路径。但是,这些示例都在C中,我宁愿不必为此编写C扩展名。
是否还有其他方法可以从Node访问这些路径,还是应该对它们进行硬编码?
答案 0 :(得分:1)
经过一些研究后,我发现可以调用相关的Windows API proc。 (SHGetKnownFolderPath)获取这些文件夹位置,请参阅文档:https://msdn.microsoft.com/en-us/library/windows/desktop/bb762188(v=vs.85).aspx。
我们使用FFI npm模块调用APi:https://www.npmjs.com/package/ffi。
可以在此处找到任何已知文件夹的GUID: https://msdn.microsoft.com/en-us/library/windows/desktop/dd378457(v=vs.85).aspx
这是一个查找几个常用文件夹位置的脚本, 一些代码有点hacky,但很容易清理。
const ffi = require('ffi');
const ref = require('ref');
const shell32 = new ffi.Library('Shell32', {
SHGetKnownFolderPath: ['int', [ ref.refType('void'), 'int', ref.refType('void'), ref.refType(ref.refType("char"))]]
});
function parseGUID(guidStr) {
var fields = guidStr.split('-');
var a1 = [];
for(var i = 0; i < fields.length; i++) {
var a2 = [...Buffer.from(fields[i], 'hex')];
if (i < 3) a2 = a2.reverse();
a1 = a1.concat(a2);
}
return new Buffer(a1);
}
function getWindowsKnownFolderPath(pathGUID) {
let guidPtr = parseGUID(pathGUID);
guidPtr.type = ref.types.void;
let pathPtr = ref.alloc(ref.refType(ref.refType("void")));
let status = shell32.SHGetKnownFolderPath(guidPtr, 0, ref.NULL, pathPtr);
if (status !== 0) {
return "Error occurred getting path: " + status;
}
let pathStr = ref.readPointer(pathPtr, 0, 200);
return pathStr.toString('ucs2').substring(0, (pathStr.indexOf('\0\0') + 1)/2);
}
// See this link for a complete list: https://msdn.microsoft.com/en-us/library/windows/desktop/dd378457(v=vs.85).aspx
const WindowsKnownFolders = {
ProgramData: "62AB5D82-FDC1-4DC3-A9DD-070D1D495D97",
Windows: "F38BF404-1D43-42F2-9305-67DE0B28FC23",
ProgramFiles: "905E63B6-C1BF-494E-B29C-65B732D3D21A",
Documents: "FDD39AD0-238F-46AF-ADB4-6C85480369C7"
}
// Enumerate common folders.
for(let [k,v] of Object.entries(WindowsKnownFolders)) {
console.log(`${k}: `, getWindowsKnownFolderPath(v));
}