PageRenderTime 51ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/Rusty/Core/Disk.cs

http://github.com/polyethene/IronAHK
C# | 982 lines | 603 code | 131 blank | 248 comment | 105 complexity | c78e4b73db9b31ab4412dfbb16199e65 MD5 | raw file
  1. using System;
  2. using System.Diagnostics;
  3. using System.IO;
  4. using System.Collections.Generic;
  5. using IronAHK.Rusty.Common;
  6. namespace IronAHK.Rusty
  7. {
  8. partial class Core
  9. {
  10. // TODO: organise Disk.cs
  11. /// <summary>
  12. /// Ejects/retracts the tray in a CD or DVD drive, or sets a drive's volume label.
  13. /// </summary>
  14. /// <param name="command"></param>
  15. /// <param name="drive">The drive letter.</param>
  16. /// <param name="value"></param>
  17. public static void Drive(string command, string drive = null, string value = null)
  18. {
  19. var cmd = command.ToLowerInvariant();
  20. #region cmd Eject
  21. if(cmd == Keyword_Eject && string.IsNullOrEmpty(value)) {
  22. if(!string.IsNullOrEmpty(drive)) {
  23. var lowDriv = Common.Drive.DriveProvider.CreateDrive(new DriveInfo(drive));
  24. lowDriv.Eject();
  25. }
  26. }
  27. #endregion
  28. #region cmd Retract / Close
  29. if(cmd == Keyword_Eject && !string.IsNullOrEmpty(value) && value == "1") {
  30. if(!string.IsNullOrEmpty(drive)) {
  31. var lowDriv = Common.Drive.DriveProvider.CreateDrive(new DriveInfo(drive));
  32. lowDriv.Retract();
  33. }
  34. }
  35. #endregion
  36. #region cmd Label
  37. if(cmd == Keyword_Label) {
  38. if(!string.IsNullOrEmpty(drive)) {
  39. try {
  40. var drv = new DriveInfo(drive);
  41. drv.VolumeLabel = string.IsNullOrEmpty(value) ? "" : value;
  42. } catch(Exception) {
  43. ErrorLevel = 1;
  44. return;
  45. }
  46. }
  47. }
  48. #endregion
  49. #region cmd Lock
  50. if(cmd == Keyword_Lock) {
  51. if(!string.IsNullOrEmpty(drive)) {
  52. }
  53. }
  54. #endregion
  55. #region cmd UnLock
  56. if(cmd == Keyword_Unlock) {
  57. if(!string.IsNullOrEmpty(drive)) {
  58. }
  59. }
  60. #endregion
  61. }
  62. /// <summary>
  63. /// Retrieves various types of information about the computer's drive(s).
  64. /// </summary>
  65. /// <param name="result">The name of the variable in which to store the result.</param>
  66. /// <param name="command"></param>
  67. /// <param name="value"></param>
  68. public static void DriveGet(out string result, string command, string value = null)
  69. {
  70. result = null;
  71. var cmd = command.ToLowerInvariant();
  72. #region cmd List
  73. if(cmd == Keyword_List){
  74. string matchingDevices = "";
  75. DriveType? type = null;
  76. if(!string.IsNullOrEmpty(value))
  77. type = Mapper.MappingService.Instance.DriveType.LookUpCLRType(value);
  78. var drives = DriveInfo.GetDrives();
  79. for(int i=0; i < drives.Length; i++) {
  80. if(type.HasValue) {
  81. if(i == 0) continue; // prefromace hack: skip A:\\
  82. try {
  83. if(drives[i].DriveType == type.Value)
  84. matchingDevices += drives[i].Name.Substring(0, 1);
  85. } catch {
  86. // ignore
  87. }
  88. } else {
  89. matchingDevices += drives[i].Name.Substring(0, 1);
  90. }
  91. }
  92. result = matchingDevices;
  93. }
  94. #endregion
  95. #region cmd Capacity
  96. if(cmd == Keyword_Capacity) {
  97. if(!string.IsNullOrEmpty(value)){
  98. try {
  99. var drv = new DriveInfo(value);
  100. result = drv.TotalSize.ToString();
  101. } catch(ArgumentException) {
  102. // value was not a valid label!
  103. ErrorLevel = 1;
  104. return;
  105. }
  106. }
  107. }
  108. #endregion
  109. #region cmd Filesystem
  110. if(cmd == Keyword_FileSystem) {
  111. if(!string.IsNullOrEmpty(value)) {
  112. try {
  113. var drv = new DriveInfo(value);
  114. result = drv.DriveFormat;
  115. } catch(ArgumentException) {
  116. // value was not a valid label!
  117. ErrorLevel = 1;
  118. return;
  119. }
  120. }
  121. }
  122. #endregion
  123. #region cmd Type
  124. if(cmd == Keyword_Type) {
  125. if(!string.IsNullOrEmpty(value)) {
  126. try {
  127. var drv = new DriveInfo(value);
  128. result = Mapper.MappingService.Instance.DriveType.LookUpIAType(drv.DriveType);
  129. } catch {
  130. // value was not a valid label!
  131. ErrorLevel = 1;
  132. return;
  133. }
  134. }
  135. }
  136. #endregion
  137. #region cmd Label
  138. if(cmd == Keyword_Label) {
  139. if(!string.IsNullOrEmpty(value)) {
  140. try {
  141. var drv = new DriveInfo(value);
  142. result = drv.VolumeLabel;
  143. } catch(ArgumentException) {
  144. // value was not a valid label!
  145. ErrorLevel = 1;
  146. return;
  147. }
  148. }
  149. }
  150. #endregion
  151. #region cmd Serial TODO!!
  152. if(cmd == Keyword_Serial) {
  153. }
  154. #endregion
  155. #region cmd Status
  156. if(cmd == Keyword_Status) {
  157. if(!string.IsNullOrEmpty(value)) {
  158. try {
  159. var drv = new DriveInfo(value);
  160. var dummy = drv.DriveFormat; // provocate DriveNotFoundException on invalid paths
  161. result = drv.IsReady ? "Ready" : "NotReady";
  162. } catch(DriveNotFoundException) {
  163. result = "Invalid";
  164. } catch(ArgumentException) {
  165. result = "Invalid";
  166. }catch{
  167. result = "Unknown";
  168. }
  169. }
  170. }
  171. #endregion
  172. #region cmd StatusCD TODO!!
  173. if(cmd == Keyword_StatusCD) {
  174. }
  175. #endregion
  176. }
  177. /// <summary>
  178. /// Retrieves the free disk space of a drive, in megabytes.
  179. /// </summary>
  180. /// <param name="result">The variable in which to store the result.</param>
  181. /// <param name="path">Path of drive to receive information from.</param>
  182. public static void DriveSpaceFree(out double result, string path)
  183. {
  184. result = Math.Floor((double)(new DriveInfo(path)).TotalFreeSpace / 1024 / 1024);
  185. }
  186. /// <summary>
  187. /// Writes text to the end of a file, creating it first if necessary.
  188. /// </summary>
  189. /// <param name="text">The text to append to <paramref name="file"/>.</param>
  190. /// <param name="file">The name of the file to be appended.
  191. /// <list type="bullet">
  192. /// <item><term>Binary mode</term>: <description>to append in binary mode rather than text mode, prepend an asterisk.</description></item>
  193. /// <item><term>Standard output (stdout)</term>: <description>specifying an asterisk (*) causes <paramref name="text"/> to be written to the console.</description></item>
  194. /// </list>
  195. /// </param>
  196. public static void FileAppend(string text, string file)
  197. {
  198. try
  199. {
  200. if (file == "*")
  201. Console.Write(text);
  202. else
  203. {
  204. if (file.Length > 0 && file[0] == '*')
  205. {
  206. file = file.Substring(1);
  207. var writer = new BinaryWriter(File.Open(file, FileMode.OpenOrCreate));
  208. writer.Write(text);
  209. }
  210. else
  211. File.AppendAllText(file, text);
  212. }
  213. ErrorLevel = 0;
  214. }
  215. catch (IOException)
  216. {
  217. ErrorLevel = 1;
  218. }
  219. }
  220. /// <summary>
  221. /// Copies one or more files.
  222. /// </summary>
  223. /// <param name="source">The name of a single file or folder, or a wildcard pattern.</param>
  224. /// <param name="destination">The name or pattern of the destination.</param>
  225. /// <param name="flag">
  226. /// <list type="bullet">
  227. /// <item><term>0</term>: <description>(default) do not overwrite existing files</description></item>
  228. /// <item><term>1</term>: <description>overwrite existing files</description></item>
  229. /// </list>
  230. /// </param>
  231. public static void FileCopy(string source, string destination, int flag = 0)
  232. {
  233. try
  234. {
  235. File.Copy(source, destination, flag != 0);
  236. ErrorLevel = 0;
  237. }
  238. catch (IOException)
  239. {
  240. ErrorLevel = 1;
  241. }
  242. }
  243. private static void CopyDirectory(string source, string destination, bool overwrite)
  244. {
  245. try
  246. {
  247. Directory.CreateDirectory(destination);
  248. }
  249. catch (IOException)
  250. {
  251. if (!overwrite)
  252. throw;
  253. }
  254. foreach (string filepath in Directory.GetFiles(source))
  255. {
  256. string basename = Path.GetFileName(filepath);
  257. string destfile = Path.Combine(destination, basename);
  258. File.Copy(filepath, destfile, overwrite);
  259. }
  260. foreach (string dirpath in Directory.GetDirectories(source))
  261. {
  262. string basename = Path.GetFileName(dirpath);
  263. string destdir = Path.Combine(destination, basename);
  264. CopyDirectory(dirpath, destdir, overwrite);
  265. }
  266. }
  267. /// <summary>
  268. /// Copies a folder along with all its sub-folders and files.
  269. /// </summary>
  270. /// <param name="source">Path of the source directory.</param>
  271. /// <param name="destination">Path of the destination directory.</param>
  272. /// <param name="flag">
  273. /// <list type="bullet">
  274. /// <item><term>0</term>: <description>(default) do not overwrite existing files</description></item>
  275. /// <item><term>1</term>: <description>overwrite existing files</description></item>
  276. /// </list>
  277. /// </param>
  278. public static void FileCopyDir(string source, string destination, int flag = 0)
  279. {
  280. var overwrite = (flag & 1) == 1;
  281. try
  282. {
  283. destination = Path.GetFullPath(destination);
  284. CopyDirectory(source, destination, overwrite);
  285. }
  286. catch (IOException)
  287. {
  288. ErrorLevel = 1;
  289. }
  290. }
  291. /// <summary>
  292. /// Creates a directory.
  293. /// </summary>
  294. /// <param name="path">Path of the directory to create.</param>
  295. public static void FileCreateDir(string path)
  296. {
  297. try
  298. {
  299. Directory.CreateDirectory(path);
  300. ErrorLevel = Directory.Exists(path) ? 0 : 1;
  301. }
  302. catch (IOException)
  303. {
  304. ErrorLevel = 1;
  305. }
  306. }
  307. /// <summary>
  308. /// Creates a shortcut to a file.
  309. /// </summary>
  310. /// <param name="target">Path to the shortcut file.</param>
  311. /// <param name="link">The file referenced by the shortcut.</param>
  312. /// <param name="workingDir">The working directory.</param>
  313. /// <param name="args">Arguments to start <paramref name="link"/> with.</param>
  314. /// <param name="description">A summary of the shortcut.</param>
  315. /// <param name="icon"></param>
  316. /// <param name="shortcutKey">A hotkey activator.</param>
  317. /// <param name="iconNumber"></param>
  318. /// <param name="runState"></param>
  319. public static void FileCreateShortcut(string target, string link, string workingDir = null, string args = null, string description = null, string icon = null, string shortcutKey = null, int iconNumber = 0, int runState = 1)
  320. {
  321. throw new NotImplementedException();
  322. }
  323. /// <summary>
  324. /// Deletes one or more files.
  325. /// </summary>
  326. /// <param name="pattern">The name of a file or a wildcard pattern.</param>
  327. public static void FileDelete(string pattern)
  328. {
  329. try
  330. {
  331. foreach (var file in Glob(pattern))
  332. File.Delete(file);
  333. ErrorLevel = 0;
  334. }
  335. catch (IOException)
  336. {
  337. ErrorLevel = 1;
  338. }
  339. }
  340. /// <summary>
  341. /// Returns the attributes of a file if it exists.
  342. /// </summary>
  343. /// <param name="pattern">The name of a file or wildcard pattern.</param>
  344. /// <returns>A blank string if no files or folders are found, otheriwse the attributes of the first match.</returns>
  345. public static string FileExist(string pattern)
  346. {
  347. try
  348. {
  349. foreach (var file in Glob(pattern))
  350. return FromFileAttribs(File.GetAttributes(file));
  351. return string.Empty;
  352. }
  353. catch (IOException)
  354. {
  355. return string.Empty;
  356. }
  357. }
  358. /// <summary>
  359. /// Retrieves information about a shortcut file.
  360. /// </summary>
  361. /// <param name="link"></param>
  362. /// <param name="target"></param>
  363. /// <param name="workingDir"></param>
  364. /// <param name="args"></param>
  365. /// <param name="description"></param>
  366. /// <param name="icon"></param>
  367. /// <param name="iconNumber"></param>
  368. /// <param name="runState"></param>
  369. public static void FileGetShortcut(string link, out string target, out string workingDir, out string args, out string description, out string icon, out string iconNumber, out string runState)
  370. {
  371. throw new NotImplementedException();
  372. }
  373. /// <summary>
  374. /// Retrieves the size of a file.
  375. /// </summary>
  376. /// <param name="result">The name of the variable in which to store the retrieved size.</param>
  377. /// <param name="file">The name of the target file.</param>
  378. /// <param name="units">
  379. /// <para>If present, this parameter causes the result to be returned in units other than bytes:</para>
  380. /// <list type="bullet">
  381. /// <item><term>K</term>: <description>kilobytes</description></item>
  382. /// <item><term>M</term>: <description>megabytes</description></item>
  383. /// <item><term>G</term>: <description>gigabytes</description></item>
  384. /// </list>
  385. /// </param>
  386. public static void FileGetSize(out long result, string file, string units = null)
  387. {
  388. try
  389. {
  390. long size = (new FileInfo(file)).Length;
  391. const int scale = 1024;
  392. if (!string.IsNullOrEmpty(units))
  393. {
  394. switch (units[0])
  395. {
  396. case 'k':
  397. case 'K':
  398. size /= scale;
  399. break;
  400. case 'm':
  401. case 'M':
  402. size /= scale * scale;
  403. break;
  404. case 'g':
  405. case 'G':
  406. size /= scale * scale * scale;
  407. break;
  408. }
  409. }
  410. result = size;
  411. }
  412. catch (Exception)
  413. {
  414. result = 0;
  415. ErrorLevel = 1;
  416. }
  417. }
  418. /// <summary>
  419. /// Retrieves the datetime stamp of a file or folder.
  420. /// </summary>
  421. /// <param name="result">The name of the variable in which to store the retrieved date-time in format YYYYMMDDHH24MISS in local time.</param>
  422. /// <param name="file">The name of the target file or folder.</param>
  423. /// <param name="time">
  424. /// <para>Which timestamp to retrieve:</para>
  425. /// <list type="bullet">
  426. /// <item><term>M</term>: <description>(default) modification time</description></item>
  427. /// <item><term>C</term>: <description>reation time</description></item>
  428. /// <item><term>A</term>: <description>last access time</description></item>
  429. /// </list>
  430. /// </param>
  431. public static void FileGetTime(out string result, string file, string time = "M")
  432. {
  433. if (!File.Exists(file))
  434. {
  435. result = string.Empty;
  436. ErrorLevel = 1;
  437. return;
  438. }
  439. var info = new FileInfo(file);
  440. var date = new DateTime();
  441. switch (time[0])
  442. {
  443. case 'm':
  444. case 'M':
  445. date = info.LastWriteTime;
  446. break;
  447. case 'c':
  448. case 'C':
  449. date = info.CreationTime;
  450. break;
  451. case 'a':
  452. case 'A':
  453. date = info.LastAccessTime;
  454. break;
  455. }
  456. result = FromTime(date).ToString();
  457. }
  458. /// <summary>
  459. /// Retrieves the version information of a file.
  460. /// </summary>
  461. /// <param name="result">The name of the variable in which to store the version number or string.</param>
  462. /// <param name="file">The name of the target file.</param>
  463. public static void FileGetVersion(out string result, string file)
  464. {
  465. result = string.Empty;
  466. try
  467. {
  468. var info = FileVersionInfo.GetVersionInfo(file);
  469. result = info.FileVersion;
  470. ErrorLevel = 0;
  471. }
  472. catch (Exception)
  473. {
  474. ErrorLevel = 1;
  475. }
  476. }
  477. /// <summary>
  478. /// Moves or renames one or more files.
  479. /// </summary>
  480. /// <param name="source">The name of a single file or a wildcard pattern.</param>
  481. /// <param name="destination">The name or pattern of the destination.</param>
  482. /// <param name="flag">
  483. /// <list type="bullet">
  484. /// <item><term>0</term>: <description>(default) do not overwrite existing files</description></item>
  485. /// <item><term>1</term>: <description>overwrite existing files</description></item>
  486. /// </list>
  487. /// </param>
  488. public static void FileMove(string source, string destination, int flag = 0)
  489. {
  490. try
  491. {
  492. if (source == destination)
  493. {
  494. ErrorLevel = 1;
  495. return;
  496. }
  497. if (File.Exists(destination))
  498. {
  499. if (flag == 0)
  500. {
  501. ErrorLevel = 1;
  502. return;
  503. }
  504. else
  505. {
  506. File.Delete(destination);
  507. }
  508. }
  509. if (File.Exists(source))
  510. {
  511. File.Move(source, destination);
  512. }
  513. }
  514. catch (Exception) { ErrorLevel = 2; }
  515. }
  516. /// <summary>
  517. /// Moves a folder along with all its sub-folders and files. It can also rename a folder.
  518. /// </summary>
  519. /// <param name="Source">Name of the source directory (with no trailing backslash), which is assumed to be in %A_WorkingDir% if an absolute path isn't specified. For example: C:\My Folder </param>
  520. /// <param name="Dest">The new path and name of the directory (with no trailing baskslash), which is assumed to be in %A_WorkingDir% if an absolute path isn't specified. For example: D:\My Folder. Note: Dest is the actual path and name that the directory will have after it is moved; it is not the directory into which Source is moved (except for the known limitation mentioned below). </param>
  521. /// <param name="Flag">
  522. /// <para>(options) Specify one of the following single characters:</para>
  523. /// <para>0 (default): Do not overwrite existing files. The operation will fail if Dest already exists as a file or directory.</para>
  524. /// <para>1: Overwrite existing files. However, any files or subfolders inside Dest that do not have a counterpart in Source will not be deleted. Known limitation: If Dest already exists as a folder and it is on the same volume as Source, Source will be moved into it rather than overwriting it. To avoid this, see the next option.</para>
  525. /// <para>2: The same as mode 1 above except that the limitation is absent.</para>
  526. /// <para>R: Rename the directory rather than moving it. Although renaming normally has the same effect as moving, it is helpful in cases where you want "all or none" behavior; that is, when you don't want the operation to be only partially successful when Source or one of its files is locked (in use). Although this method cannot move Source onto a different volume, it can move it to any other directory on its own volume. The operation will fail if Dest already exists as a file or directory.</para>
  527. /// </param>
  528. public static void FileMoveDir(string Source, string Dest, string Flag)
  529. {
  530. ErrorLevel = 0;
  531. switch (Flag)
  532. {
  533. case "0":
  534. if (Directory.Exists(Dest))
  535. return;
  536. break;
  537. default:
  538. ErrorLevel = 1;
  539. return;
  540. }
  541. Directory.Move(Source, Dest);
  542. }
  543. /// <summary>
  544. /// Read the contents of a file.
  545. /// </summary>
  546. /// <param name="OutputVar">The name of the variable in which to store the retrieved content.</param>
  547. /// <param name="Filename">
  548. /// <para>The file path, optionally preceded by one or more of the following options:</para>
  549. /// <list type="bullet">
  550. /// <item><term>*c</term>: <description>treat the source as binary rather than text, <paramref name="OutputVar"/> will be a byte array.</description></item>
  551. /// <item><term>*m<c>n</c></term>: <description>stop reading at <c>n</c> bytes.</description></item>
  552. /// <item><term>*t</term>: <description>replace all occurrences of <c>`r`n</c> with <c>`n</c>. This option is ignored in binary mode.</description></item>
  553. /// </list>
  554. /// </param>
  555. public static void FileRead(out object OutputVar, string Filename)
  556. {
  557. #region Variables
  558. OutputVar = null;
  559. ErrorLevel = 0;
  560. if (string.IsNullOrEmpty(Filename))
  561. {
  562. ErrorLevel = 1;
  563. return;
  564. }
  565. #endregion
  566. #region Options
  567. bool binary = false, nocrlf = false;
  568. int i, max = -1;
  569. while ((i = Filename.IndexOf('*')) != -1)
  570. {
  571. int n = i + 1;
  572. if (n == Filename.Length)
  573. {
  574. Filename = i == 0 ? string.Empty : Filename.Substring(0, i);
  575. break;
  576. }
  577. char mode = Filename[n++];
  578. switch (mode)
  579. {
  580. case 'c':
  581. case 'C':
  582. binary = true;
  583. break;
  584. case 't':
  585. case 'T':
  586. nocrlf = true;
  587. break;
  588. case 'm':
  589. case 'M':
  590. int s = n;
  591. while (n < Filename.Length && char.IsDigit(Filename, n))
  592. n++;
  593. if (s < n)
  594. max = int.Parse(Filename.Substring(s, n - s));
  595. break;
  596. }
  597. if (n == Filename.Length)
  598. Filename = Filename.Substring(0, n);
  599. else if (i == 0)
  600. Filename = Filename.Substring(n);
  601. else
  602. Filename = Filename.Substring(0, i) + Filename.Substring(n);
  603. }
  604. if (max == 0)
  605. return;
  606. if (Filename.Length == 0)
  607. {
  608. ErrorLevel = 1;
  609. return;
  610. }
  611. #endregion
  612. #region Read
  613. if (binary)
  614. {
  615. try
  616. {
  617. if (max == -1)
  618. OutputVar = File.ReadAllBytes(Filename);
  619. else
  620. OutputVar = new BinaryReader(File.OpenRead(Filename)).ReadBytes(max);
  621. }
  622. catch (Exception)
  623. {
  624. ErrorLevel = 1;
  625. return;
  626. }
  627. }
  628. else
  629. {
  630. string text;
  631. try
  632. {
  633. text = File.ReadAllText(Filename);
  634. }
  635. catch (Exception)
  636. {
  637. ErrorLevel = 1;
  638. return;
  639. }
  640. if (max != -1)
  641. text = text.Substring(0, max);
  642. if (nocrlf)
  643. text = text.Replace("\r\n", "\n");
  644. OutputVar = text;
  645. }
  646. #endregion
  647. }
  648. /// <summary>
  649. /// Reads the specified line from a file and stores the text in a variable.
  650. /// </summary>
  651. /// <param name="OutputVar">The name of the variable in which to store the retrieved text.</param>
  652. /// <param name="Filename">The name of the file to access, which is assumed to be in %A_WorkingDir% if an absolute path isn't specified. Windows and Unix formats are supported; that is, the file's lines may end in either carriage return and linefeed (`r`n) or just linefeed (`n).</param>
  653. /// <param name="LineNum">Which line to read (1 is the first, 2 the second, and so on).</param>
  654. public static void FileReadLine(out string OutputVar, string Filename, int LineNum)
  655. {
  656. OutputVar = string.Empty;
  657. try
  658. {
  659. var sr = new StreamReader(Filename);
  660. string line = string.Empty;
  661. for (int i = 0; i < LineNum; i++)
  662. line = sr.ReadLine();
  663. sr.Close();
  664. OutputVar = line;
  665. ErrorLevel = 0;
  666. }
  667. catch (Exception) { ErrorLevel = 1; }
  668. }
  669. /// <summary>
  670. /// Sends a file or directory to the recycle bin, if possible.
  671. /// </summary>
  672. /// <param name="FilePattern">
  673. /// <para>The name of a single file or a wildcard pattern such as C:\Temp\*.tmp. FilePattern is assumed to be in %A_WorkingDir% if an absolute path isn't specified.</para>
  674. /// <para>To recycle an entire directory, provide its name without a trailing backslash.</para>
  675. /// </param>
  676. public static void FileRecycle(string FilePattern)
  677. {
  678. }
  679. /// <summary>
  680. /// Empties the recycle bin.
  681. /// </summary>
  682. /// <param name="Root">If omitted, the recycle bin for all drives is emptied. Otherwise, specify a drive letter such as C:\</param>
  683. public static void FileRecycleEmpty(string Root)
  684. {
  685. try
  686. {
  687. WindowsAPI.SHEmptyRecycleBin(IntPtr.Zero, Root, WindowsAPI.SHERB_NOCONFIRMATION | WindowsAPI.SHERB_NOPROGRESSUI | WindowsAPI.SHERB_NOSOUND);
  688. ErrorLevel = 0;
  689. }
  690. catch (Exception) { ErrorLevel = 1; }
  691. }
  692. /// <summary>
  693. /// Deletes a folder.
  694. /// </summary>
  695. /// <param name="Path">Name of the directory to delete, which is assumed to be in %A_WorkingDir% if an absolute path isn't specified.</param>
  696. /// <param name="Recurse">
  697. /// <list type="">
  698. /// <item>0 (default): Do not remove files and sub-directories contained in DirName. In this case, if DirName is not empty, no action will be taken and ErrorLevel will be set to 1.</item>
  699. /// <item>1: Remove all files and subdirectories (like the DOS DelTree command).</item>
  700. /// </list>
  701. /// </param>
  702. public static void FileRemoveDir(string Path, bool Recurse)
  703. {
  704. try
  705. {
  706. Directory.Delete(Path, Recurse);
  707. ErrorLevel = 0;
  708. }
  709. catch (Exception) { ErrorLevel = 1; }
  710. }
  711. /// <summary>
  712. /// Changes the attributes of one or more files or folders. Wildcards are supported.
  713. /// </summary>
  714. /// <param name="Attributes">The attributes to change (see Remarks).</param>
  715. /// <param name="FilePattern">
  716. /// <para>The name of a single file or folder, or a wildcard pattern such as C:\Temp\*.tmp. FilePattern is assumed to be in %A_WorkingDir% if an absolute path isn't specified.</para>
  717. /// <para>If omitted, the current file of the innermost enclosing File-Loop will be used instead.</para>
  718. /// </param>
  719. /// <param name="OperateOnFolders">
  720. /// <list type="">
  721. /// <item>0 (default) Folders are not operated upon (only files).</item>
  722. /// <item>1 All files and folders that match the wildcard pattern are operated upon.</item>
  723. /// <item>2 Only folders are operated upon (no files).</item>
  724. /// </list>
  725. /// <para>Note: If FilePattern is a single folder rather than a wildcard pattern, it will always be operated upon regardless of this setting.</para>
  726. /// </param>
  727. /// <param name="Recurse">
  728. /// <list type="">
  729. /// <item>0 (default) Subfolders are not recursed into.</item>
  730. /// <item>1 Subfolders are recursed into so that files and folders contained therein are operated upon if they match FilePattern. All subfolders will be recursed into, not just those whose names match FilePattern. However, files and folders with a complete path name longer than 259 characters are skipped over as though they do not exist. Such files are rare because normally, the operating system does not allow their creation.</item>
  731. /// </list>
  732. /// </param>
  733. public static void FileSetAttrib(string Attributes, string FilePattern, int OperateOnFolders, int Recurse)
  734. {
  735. try
  736. {
  737. int error = 0;
  738. foreach (var path in ToFiles(FilePattern, OperateOnFolders != 2, OperateOnFolders != 0, Recurse != 0))
  739. {
  740. FileAttributes set = ToFileAttribs(Attributes, File.GetAttributes(path));
  741. File.SetAttributes(path, set);
  742. if (File.GetAttributes(path) != set)
  743. error++;
  744. }
  745. ErrorLevel = error;
  746. }
  747. catch (Exception) { ErrorLevel = 1; }
  748. }
  749. /// <summary>
  750. /// Changes the datetime stamp of one or more files or folders. Wildcards are supported.
  751. /// </summary>
  752. /// <param name="YYYYMMDDHH24MISS">If blank or omitted, it defaults to the current time. Otherwise, specify the time to use for the operation (see Remarks for the format). Years prior to 1601 are not supported.</param>
  753. /// <param name="FilePattern">
  754. /// <para>The name of a single file or folder, or a wildcard pattern such as C:\Temp\*.tmp. FilePattern is assumed to be in %A_WorkingDir% if an absolute path isn't specified.</para>
  755. /// <para>If omitted, the current file of the innermost enclosing File-Loop will be used instead.</para>
  756. /// </param>
  757. /// <param name="WhichTime">Which timestamp to set:
  758. /// <list type="">
  759. /// <item>M = Modification time (this is the default if the parameter is blank or omitted)</item>
  760. /// <item>C = Creation time</item>
  761. /// <item>A = Last access time </item>
  762. /// </list>
  763. /// </param>
  764. /// <param name="OperateOnFolders">
  765. /// <list type="">
  766. /// <item>0 (default) Folders are not operated upon (only files).</item>
  767. /// <item>1 All files and folders that match the wildcard pattern are operated upon.</item>
  768. /// <item>2 Only folders are operated upon (no files).</item>
  769. /// <para>Note: If FilePattern is a single folder rather than a wildcard pattern, it will always be operated upon regardless of this setting.</para>
  770. /// </list>
  771. /// </param>
  772. /// <param name="Recurse">
  773. /// <list type="">
  774. /// <item>0 (default) Subfolders are not recursed into.</item>
  775. /// <item>1 Subfolders are recursed into so that files and folders contained therein are operated upon if they match FilePattern. All subfolders will be recursed into, not just those whose names match FilePattern. However, files and folders with a complete path name longer than 259 characters are skipped over as though they do not exist. Such files are rare because normally, the operating system does not allow their creation.</item>
  776. /// </list>
  777. /// </param>
  778. public static void FileSetTime(string YYYYMMDDHH24MISS, string FilePattern, string WhichTime, int OperateOnFolders, int Recurse)
  779. {
  780. DateTime time = ToDateTime(YYYYMMDDHH24MISS);
  781. try
  782. {
  783. int error = 0;
  784. foreach (var path in ToFiles(FilePattern, OperateOnFolders != 2, OperateOnFolders != 0, Recurse != 0))
  785. {
  786. var set = new DateTime();
  787. switch (WhichTime[0])
  788. {
  789. case 'm':
  790. case 'M':
  791. File.SetLastWriteTime(path, time);
  792. set = File.GetLastWriteTime(path);
  793. break;
  794. case 'c':
  795. case 'C':
  796. File.SetCreationTime(path, time);
  797. set = File.GetCreationTime(path);
  798. break;
  799. case 'a':
  800. case 'A':
  801. File.SetLastAccessTime(path, time);
  802. set = File.GetLastAccessTime(path);
  803. break;
  804. default:
  805. throw new ArgumentOutOfRangeException();
  806. }
  807. if (set != time)
  808. error++;
  809. }
  810. ErrorLevel = error;
  811. }
  812. catch (Exception) { ErrorLevel = 1; }
  813. }
  814. /// <summary>
  815. /// Changes the script's current working directory.
  816. /// </summary>
  817. /// <param name="DirName">The name of the new working directory, which is assumed to be a subfolder of the current %A_WorkingDir% if an absolute path isn't specified.</param>
  818. public static void SetWorkingDir(string DirName)
  819. {
  820. Environment.CurrentDirectory = DirName;
  821. }
  822. /// <summary>
  823. /// Separates a file name or URL into its name, directory, extension, and drive.
  824. /// </summary>
  825. /// <param name="path">Name of the variable containing the file name to be analyzed.</param>
  826. /// <param name="filename">Name of the variable in which to store the file name without its path. The file's extension is included.</param>
  827. /// <param name="directory">Name of the variable in which to store the directory of the file, including drive letter or share name (if present). The final backslash is not included even if the file is located in a drive's root directory.</param>
  828. /// <param name="extension">Name of the variable in which to store the file's extension (e.g. TXT, DOC, or EXE). The dot is not included.</param>
  829. /// <param name="name">Name of the variable in which to store the file name without its path, dot and extension.</param>
  830. /// <param name="root">Name of the variable in which to store the drive letter or server name of the file. If the file is on a local or mapped drive, the variable will be set to the drive letter followed by a colon (no backslash). If the file is on a network path (UNC), the variable will be set to the share name, e.g. \\Workstation01</param>
  831. public static void SplitPath(ref string path, out string filename, out string directory, out string extension, out string name, out string root)
  832. {
  833. var input = path;
  834. try
  835. {
  836. input = Path.GetFullPath(path);
  837. }
  838. catch (ArgumentException)
  839. {
  840. ErrorLevel = 1;
  841. filename = directory = extension = name = root = null;
  842. return;
  843. }
  844. filename = Path.GetFileName(input);
  845. directory = Path.GetDirectoryName(input);
  846. extension = Path.GetExtension(input);
  847. name = Path.GetFileNameWithoutExtension(input);
  848. root = Path.GetPathRoot(input);
  849. }
  850. }
  851. }