UNPKG

fswin32

Version:

The ultimate Node.js module for detailed Windows file system access.

86 lines (75 loc) 3.15 kB
// src/drives.js import { promises as fs } from 'fs'; import { executePowerShellCommand, formatBytes } from './utils.js'; /** * Gets a list of accessible Windows drives. * It first checks all A-Z drive letters directly using fs.access for speed. * PowerShell is used only as a last resort fallback if no drives are found. * @returns {Promise<Array<string>>} An array of accessible drive letters. */ export const getAccessibleDrives = async () => { let drives = []; const driveLetters = []; // Primary, faster method: Check A-Z drives with fs.access for (let i = 65; i <= 90; i++) { driveLetters.push(String.fromCharCode(i)); } // Use Promise.all to check all drives concurrently for max speed const driveAccessChecks = driveLetters.map(async (letter) => { const drivePath = `${letter}:\\`; try { await fs.access(drivePath); return letter; } catch (error) { return null; // Drive is not accessible, return null } }); const results = await Promise.all(driveAccessChecks); drives = results.filter(Boolean); // Filter out null values // Fallback only if no drives are found through the fast method if (drives.length === 0) { const stdout = await executePowerShellCommand('Get-WmiObject -Class Win32_LogicalDisk | Select-Object DeviceID'); if (stdout) { stdout.split('\n').forEach(line => { const match = line.match(/^([A-Z]):/); if (match) drives.push(match[1]); }); } } return [...new Set(drives)]; }; /** * Gets detailed information about a specific Windows drive using PowerShell. * @param {string} driveLetter The letter of the drive (e.g., 'C'). * @returns {Promise<Object|null>} An object with drive details or null on failure. */ export const getDriveDetails = async (driveLetter) => { const command = `Get-WmiObject -Class Win32_LogicalDisk | Where-Object {$_.DeviceID -eq '${driveLetter}:'} | Select-Object Size, FreeSpace, VolumeName | Format-List`; const stdout = await executePowerShellCommand(command); if (stdout) { const lines = stdout.split('\n').filter(line => line.trim()); const details = {}; lines.forEach(line => { const [key, value] = line.split(':').map(s => s.trim()); if (key && value) { details[key] = value; } }); if (details.Size && details.FreeSpace) { const totalSpaceBytes = parseInt(details.Size, 10); const freeSpaceBytes = parseInt(details.FreeSpace, 10); const usedSpaceBytes = totalSpaceBytes - freeSpaceBytes; return { drive: driveLetter, volumeName: details.VolumeName || 'N/A', totalSpace: formatBytes(totalSpaceBytes), freeSpace: formatBytes(freeSpaceBytes), usedSpace: formatBytes(usedSpaceBytes), totalSpaceBytes, freeSpaceBytes, usedSpaceBytes, }; } } return null; };