// This program will create a comprehensive list of all files // and directories starting from the directory specified and // saves the resulting list in a file. (The list will be sorted by file size.) // Written in JavaScript by Zsolt Nagy-Perge in July 2022 $RECURSIVE = 0; $DIRECTORY = "C:\\DESKTOP"; $OUTPUT_FILE = "Z:\\Output.txt"; ////////////////////////////////////////////////// if (!RequestFileSystemAccess()) Die("Can't get permission to use file system object\n\n" + $ERROR_MESSAGE); Exit_If_Cancel("File Directory Reader", "This JavaScript program demonstrates how to read directory contents\nin pure JS on Windows platforms. If you don't want to run this script,\npress Cancel, otherwise it will look for files in\n\nDIRECTORY: " + $DIRECTORY + "\nRECURSEIVE = " + $RECURSIVE + "\nOUTPUT FILE = " + $OUTPUT_FILE); OUTPUT = []; // Global array where file list will be stored ReadDIR($DIRECTORY); // Read directory contents OUTPUT.sort(); // Sort list by file size $HEADER = "# Starting point: " + $DIRECTORY + "\r\n# Created on: " + FormatDate() + "\r\n# FileSize LastModifiedDate Signature FileName\r\n"; // Write file list to output file. CreateUnicodeTextFile($OUTPUT_FILE, $HEADER + OUTPUT.join("\r\n")); ////////////////////////////////////////////////// // // Creates a text file in Unicode format. // function CreateUnicodeTextFile($FILENAME, $CONTENT) { try { var $FORMAT = true; // true=UTF8 false=ASCII var $CREATE_IF_NOT_EXIST = true; var F = FSO.CreateTextFile($FILENAME, $CREATE_IF_NOT_EXIST, $FORMAT); F.Write($CONTENT); F.Close(); Alert("File saved successfully!\n\n" + $OUTPUT_FILE); } catch (e) { Die("Couldn't save file.\n\n" + e.message); } } ////////////////////////////////////////////////// // // This function walks all subdirectories starting at $PATH // and saves the list of file and folder names in a global // array named OUTPUT // function ReadDIR($PATH) { var F = FSO.GetFolder($PATH); // Process directories... for (var FC = new Enumerator(F.SubFolders); !FC.atEnd(); FC.moveNext()) { var $SUBDIR = FC.item(); if ($RECURSIVE) ReadDIR($SUBDIR); } // Process files... for (var FC = new Enumerator(F.files); !FC.atEnd(); FC.moveNext()) { var $FileName = FC.item() + ''; var FileObject = FSO.GetFile($FileName); var $FileSize = FileObject.Size; var $FileDate = FileObject.DateLastModified; var $LastModified = FormatDate($FileDate); var $Signature = ReadFileSignature($FileName) OUTPUT.push(PAD(11, $FileSize) + ' ' + $LastModified + ' ' + $Signature + ' ' + $FileName); } } ////////////////////////////////////////////////// // // This function opens a file and reads the first 4 bytes // and returns those bytes in hexadecimal format. // function ReadFileSignature($FILENAME) { var $SIG = ReadFile($FILENAME, 0, 4, 0); // Convert signature to hexadecimal format and add padding with dots from the right // in case a file size is zero and there's no file signature. return PAD(8, Str2Hex($SIG), '.', 1); } ////////////////////////////////////////////////// // // This function expects the date in milliseconds since January 1st, 1970 // and returns it in the format: YYYY-MM-DD HH:MM:SS. // With no arguments, this function simply returns the // current date in the above mentioned format. // function FormatDate(milliseconds) { var D = new Date(); if (arguments.length > 0) D.setTime(milliseconds); return D.getFullYear() + '-' + PAD(2, D.getMonth() * 1 + 1) + '-' + PAD(2, D.getDate()) + ' ' + PAD(2, D.getHours()) + ':' + PAD(2, D.getMinutes()) + ':' + PAD(2, D.getSeconds()); } ////////////////////////////////////////////////// // // This function requests access to the file system, // and normally, it is granted. Returns 1=GRANTED, 0=DENIED // function RequestFileSystemAccess() { $ERROR_MESSAGE = ''; // This will become a global variable. try { // FSO is going to be a global variable. FSO = new ActiveXObject("Scripting.FileSystemObject"); return 1; } catch(e) { $ERROR_MESSAGE = "Can't get permission to use file system object!\n\n" + e.message; return 0; } } ////////////////////////////////////////////////// // // Terminates this script and returns with errorcode 1. // function Die($msg) { if (arguments.length > 0) Alert($msg); WScript.Quit(1); } ////////////////////////////////////////////////// // // Displays a small pop up message box in Windows. // function Alert($msg) { WScript.Echo($msg); } ////////////////////////////////////////////////// // // Adds padding character CHAR in front of X and // makes sure that string X is going to be exactly // N characters long. It will not be longer or shorter. // When argument CHAR is omitted, a zero will be used // as padding character. // When argument D is provided, the padding will // be added to the right side of X. // Usage: STRING = PAD(LENGTH, STRING, [PADDING_CHAR, [FROM_RIGHT]]) // function PAD($N, $X, $CHAR, $D) { $N |= 0; if ($N <= 0 || $N > 99999) return ''; if (typeof($X) === 'undefined') $X = ''; else $X += ''; if ($X.length > $N) return $X.slice($X.length - $N); $CHAR = (typeof($CHAR) === 'undefined') ? '0' : ($CHAR + '0').substr(0, 1); if (arguments.length < 4) while ($X.length < $N) $X = $CHAR + $X; else while ($X.length < $N) $X += $CHAR; return $X; } ////////////////////////////////////////////////// // v2021.4.24 // Reads an entire binary file or text file // and returns its contents as a string. // // START: File pointer for where to start reading (default is 0) // LENGTH: 0=Read entire file (default) N=Read N number of bytes // FORMAT: 0=ASCII/BINARY (default) 1=UNICODE TEXT // Usage: STRING = ReadFile(FILENAME, [START, [LENGTH, [FORMAT]]]) // function ReadFile($FILENAME, $START, $LENGTH, $FMT) { $FMT |= 0; $START |= 0; $LENGTH |= 0; var $DATA = ''; try { var F = FSO.OpenTextFile($FILENAME, 1, 0, $FMT); if ($START) F.Skip($START); $DATA = ($LENGTH) ? F.Read($LENGTH) : F.ReadAll(); F.Close(); return $DATA; } catch (e) {} return ''; } ////////////////////////////////////////////////// // v2021.3.30 // This function converts an ASCII string to a // series of hex numbers. // function Str2Hex($S) { var $c, $i, OUT = []; for ($i = 0; $i < $S.length; $i++) { $c = $S.charCodeAt($i) & 255; OUT.push(($c < 16 ? '0' : '') + $c.toString(16)); } return OUT.join('').toUpperCase(); } ////////////////////////////////////////////////// // // This function will display an OK-OR-CANCEL popup // window with some message. If the user clicks // Cancel, the script terminates. // function Exit_If_Cancel($title, $msg) { var $Answer = 0; try { var WshShell = WScript.CreateObject("WScript.Shell"); $Answer = WshShell.Popup($msg, 1000, $title, 33); } catch(e) { Alert($msg); } if ($Answer == 2) WScript.Quit(0); } //////////////////////////////////////////////////