You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

460 lines
30 KiB

  1. /* Copyright (C) 2008-2016 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov
  2. *
  3. * Permission is hereby granted, free of charge, to any person obtaining a copy
  4. * of this software and associated documentation files (the "Software"), to deal
  5. * in the Software without restriction, including without limitation the rights
  6. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. * copies of the Software, and to permit persons to whom the Software is
  8. * furnished to do so, subject to the following conditions:
  9. *
  10. * The above copyright notice and this permission notice shall be included in
  11. * all copies or substantial portions of the Software.
  12. *
  13. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  19. * THE SOFTWARE.
  20. */
  21. using System;
  22. using System.IO;
  23. using System.Security;
  24. namespace Alphaleonis.Win32.Filesystem
  25. {
  26. partial class DirectoryInfo
  27. {
  28. #region CopyTo
  29. // .NET: Directory class does not contain the Copy() method.
  30. // Mimic .NET File.Copy() methods.
  31. /// <summary>[AlphaFS] Copies a <see cref="DirectoryInfo"/> instance and its contents to a new path.
  32. /// <remarks>
  33. /// <para>Use this method to prevent overwriting of an existing directory by default.</para>
  34. /// <para>Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method.</para>
  35. /// <para>If two directories have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior.</para>
  36. /// </remarks>
  37. /// </summary>
  38. /// <returns>A new <see cref="DirectoryInfo"/> instance if the directory was completely copied.</returns>
  39. /// <exception cref="ArgumentException"/>
  40. /// <exception cref="ArgumentNullException"/>
  41. /// <exception cref="DirectoryNotFoundException"/>
  42. /// <exception cref="IOException"/>
  43. /// <exception cref="NotSupportedException"/>
  44. /// <exception cref="UnauthorizedAccessException"/>
  45. /// <param name="destinationPath">The destination directory path.</param>
  46. [SecurityCritical]
  47. public DirectoryInfo CopyTo(string destinationPath)
  48. {
  49. string destinationPathLp;
  50. CopyToMoveToCore(destinationPath, CopyOptions.FailIfExists, null, null, null, out destinationPathLp, PathFormat.RelativePath);
  51. return new DirectoryInfo(Transaction, destinationPathLp, PathFormat.LongFullPath);
  52. }
  53. /// <summary>[AlphaFS] Copies a <see cref="DirectoryInfo"/> instance and its contents to a new path.
  54. /// <remarks>
  55. /// <para>Use this method to prevent overwriting of an existing directory by default.</para>
  56. /// <para>Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method.</para>
  57. /// <para>If two directories have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior.</para>
  58. /// </remarks>
  59. /// </summary>
  60. /// <returns>A new <see cref="DirectoryInfo"/> instance if the directory was completely copied.</returns>
  61. /// <exception cref="ArgumentException"/>
  62. /// <exception cref="ArgumentNullException"/>
  63. /// <exception cref="DirectoryNotFoundException"/>
  64. /// <exception cref="IOException"/>
  65. /// <exception cref="NotSupportedException"/>
  66. /// <exception cref="UnauthorizedAccessException"/>
  67. /// <param name="destinationPath">The destination directory path.</param>
  68. /// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
  69. [SecurityCritical]
  70. public DirectoryInfo CopyTo(string destinationPath, PathFormat pathFormat)
  71. {
  72. string destinationPathLp;
  73. CopyToMoveToCore(destinationPath, CopyOptions.FailIfExists, null, null, null, out destinationPathLp, pathFormat);
  74. return new DirectoryInfo(Transaction, destinationPathLp, PathFormat.LongFullPath);
  75. }
  76. /// <summary>[AlphaFS] Copies an existing directory to a new directory, allowing the overwriting of an existing directory, <see cref="CopyOptions"/> can be specified.
  77. /// <remarks>
  78. /// <para>Option <see cref="CopyOptions.NoBuffering"/> is recommended for very large file transfers.</para>
  79. /// <para>Use this method to allow or prevent overwriting of an existing directory.</para>
  80. /// <para>Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method.</para>
  81. /// <para>If two directories have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior.</para>
  82. /// </remarks>
  83. /// </summary>
  84. /// <returns>
  85. /// <para>Returns a new directory, or an overwrite of an existing directory if <paramref name="copyOptions"/> is not <see cref="CopyOptions.FailIfExists"/>.</para>
  86. /// <para>If the directory exists and <paramref name="copyOptions"/> contains <see cref="CopyOptions.FailIfExists"/>, an <see cref="IOException"/> is thrown.</para>
  87. /// </returns>
  88. /// <exception cref="ArgumentException"/>
  89. /// <exception cref="ArgumentNullException"/>
  90. /// <exception cref="DirectoryNotFoundException"/>
  91. /// <exception cref="IOException"/>
  92. /// <exception cref="NotSupportedException"/>
  93. /// <exception cref="UnauthorizedAccessException"/>
  94. /// <param name="destinationPath">The destination directory path.</param>
  95. /// <param name="copyOptions"><see cref="CopyOptions"/> that specify how the directory is to be copied. This parameter can be <see langword="null"/>.</param>
  96. [SecurityCritical]
  97. public DirectoryInfo CopyTo(string destinationPath, CopyOptions copyOptions)
  98. {
  99. string destinationPathLp;
  100. CopyToMoveToCore(destinationPath, copyOptions, null, null, null, out destinationPathLp, PathFormat.RelativePath);
  101. return new DirectoryInfo(Transaction, destinationPathLp, PathFormat.LongFullPath);
  102. }
  103. /// <summary>[AlphaFS] Copies an existing directory to a new directory, allowing the overwriting of an existing directory, <see cref="CopyOptions"/> can be specified.
  104. /// <remarks>
  105. /// <para>Option <see cref="CopyOptions.NoBuffering"/> is recommended for very large file transfers.</para>
  106. /// <para>Use this method to allow or prevent overwriting of an existing directory.</para>
  107. /// <para>Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method.</para>
  108. /// <para>If two directories have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior.</para>
  109. /// </remarks>
  110. /// </summary>
  111. /// <returns>
  112. /// <para>Returns a new directory, or an overwrite of an existing directory if <paramref name="copyOptions"/> is not <see cref="CopyOptions.FailIfExists"/>.</para>
  113. /// <para>If the directory exists and <paramref name="copyOptions"/> contains <see cref="CopyOptions.FailIfExists"/>, an <see cref="IOException"/> is thrown.</para>
  114. /// </returns>
  115. /// <exception cref="ArgumentException"/>
  116. /// <exception cref="ArgumentNullException"/>
  117. /// <exception cref="DirectoryNotFoundException"/>
  118. /// <exception cref="IOException"/>
  119. /// <exception cref="NotSupportedException"/>
  120. /// <exception cref="UnauthorizedAccessException"/>
  121. /// <param name="destinationPath">The destination directory path.</param>
  122. /// <param name="copyOptions"><see cref="CopyOptions"/> that specify how the directory is to be copied. This parameter can be <see langword="null"/>.</param>
  123. /// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
  124. [SecurityCritical]
  125. public DirectoryInfo CopyTo(string destinationPath, CopyOptions copyOptions, PathFormat pathFormat)
  126. {
  127. string destinationPathLp;
  128. CopyToMoveToCore(destinationPath, copyOptions, null, null, null, out destinationPathLp, pathFormat);
  129. return new DirectoryInfo(Transaction, destinationPathLp, PathFormat.LongFullPath);
  130. }
  131. /// <summary>[AlphaFS] Copies an existing directory to a new directory, allowing the overwriting of an existing directory, <see cref="CopyOptions"/> can be specified.
  132. /// <para>and the possibility of notifying the application of its progress through a callback function.</para>
  133. /// <remarks>
  134. /// <para>Option <see cref="CopyOptions.NoBuffering"/> is recommended for very large file transfers.</para>
  135. /// <para>Use this method to allow or prevent overwriting of an existing directory.</para>
  136. /// <para>Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method.</para>
  137. /// <para>If two directories have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior.</para>
  138. /// </remarks>
  139. /// </summary>
  140. /// <returns>A <see cref="CopyMoveResult"/> class with details of the Copy action.</returns>
  141. /// <exception cref="ArgumentException"/>
  142. /// <exception cref="ArgumentNullException"/>
  143. /// <exception cref="DirectoryNotFoundException"/>
  144. /// <exception cref="IOException"/>
  145. /// <exception cref="NotSupportedException"/>
  146. /// <exception cref="UnauthorizedAccessException"/>
  147. /// <param name="destinationPath">The destination directory path.</param>
  148. /// <param name="copyOptions"><see cref="CopyOptions"/> that specify how the directory is to be copied. This parameter can be <see langword="null"/>.</param>
  149. /// <param name="progressHandler">A callback function that is called each time another portion of the directory has been copied. This parameter can be <see langword="null"/>.</param>
  150. /// <param name="userProgressData">The argument to be passed to the callback function. This parameter can be <see langword="null"/>.</param>
  151. [SecurityCritical]
  152. public CopyMoveResult CopyTo(string destinationPath, CopyOptions copyOptions, CopyMoveProgressRoutine progressHandler, object userProgressData)
  153. {
  154. string destinationPathLp;
  155. var cmr = CopyToMoveToCore(destinationPath, copyOptions, null, progressHandler, userProgressData, out destinationPathLp, PathFormat.RelativePath);
  156. CopyToMoveToCoreRefresh(destinationPath, destinationPathLp);
  157. return cmr;
  158. }
  159. /// <summary>[AlphaFS] Copies an existing directory to a new directory, allowing the overwriting of an existing directory, <see cref="CopyOptions"/> can be specified.
  160. /// <para>and the possibility of notifying the application of its progress through a callback function.</para>
  161. /// <remarks>
  162. /// <para>Option <see cref="CopyOptions.NoBuffering"/> is recommended for very large file transfers.</para>
  163. /// <para>Use this method to allow or prevent overwriting of an existing directory.</para>
  164. /// <para>Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method.</para>
  165. /// <para>If two directories have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior.</para>
  166. /// </remarks>
  167. /// </summary>
  168. /// <returns>A <see cref="CopyMoveResult"/> class with details of the Copy action.</returns>
  169. /// <exception cref="ArgumentException"/>
  170. /// <exception cref="ArgumentNullException"/>
  171. /// <exception cref="DirectoryNotFoundException"/>
  172. /// <exception cref="IOException"/>
  173. /// <exception cref="NotSupportedException"/>
  174. /// <exception cref="UnauthorizedAccessException"/>
  175. /// <param name="destinationPath">The destination directory path.</param>
  176. /// <param name="copyOptions"><see cref="CopyOptions"/> that specify how the directory is to be copied. This parameter can be <see langword="null"/>.</param>
  177. /// <param name="progressHandler">A callback function that is called each time another portion of the directory has been copied. This parameter can be <see langword="null"/>.</param>
  178. /// <param name="userProgressData">The argument to be passed to the callback function. This parameter can be <see langword="null"/>.</param>
  179. /// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
  180. [SecurityCritical]
  181. public CopyMoveResult CopyTo(string destinationPath, CopyOptions copyOptions, CopyMoveProgressRoutine progressHandler, object userProgressData, PathFormat pathFormat)
  182. {
  183. string destinationPathLp;
  184. var cmr = CopyToMoveToCore(destinationPath, copyOptions, null, progressHandler, userProgressData, out destinationPathLp, pathFormat);
  185. CopyToMoveToCoreRefresh(destinationPath, destinationPathLp);
  186. return cmr;
  187. }
  188. #endregion // CopyTo
  189. #region MoveTo
  190. #region .NET
  191. /// <summary>Moves a <see cref="DirectoryInfo"/> instance and its contents to a new path.
  192. /// <remarks>
  193. /// <para>Use this method to prevent overwriting of an existing directory by default.</para>
  194. /// <para>This method does not work across disk volumes.</para>
  195. /// <para>Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method.</para>
  196. /// <para>If two directories have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior.</para>
  197. /// </remarks>
  198. /// </summary>
  199. /// <returns>A <see cref="CopyMoveResult"/> class with details of the Move action.</returns>
  200. /// <exception cref="ArgumentException"/>
  201. /// <exception cref="ArgumentNullException"/>
  202. /// <exception cref="DirectoryNotFoundException"/>
  203. /// <exception cref="IOException"/>
  204. /// <exception cref="NotSupportedException"/>
  205. /// <exception cref="UnauthorizedAccessException"/>
  206. /// <param name="destinationPath">
  207. /// <para>The name and path to which to move this directory.</para>
  208. /// <para>The destination cannot be another disk volume or a directory with the identical name.</para>
  209. /// <para>It can be an existing directory to which you want to add this directory as a subdirectory.</para>
  210. /// </param>
  211. [SecurityCritical]
  212. public CopyMoveResult MoveTo(string destinationPath)
  213. {
  214. string destinationPathLp;
  215. var copyMoveResult = CopyToMoveToCore(destinationPath, null, MoveOptions.None, null, null, out destinationPathLp, PathFormat.RelativePath);
  216. CopyToMoveToCoreRefresh(destinationPath, destinationPathLp);
  217. return copyMoveResult;
  218. }
  219. #endregion // .NET
  220. #region AlphaFS
  221. /// <summary>Moves a <see cref="DirectoryInfo"/> instance and its contents to a new path.
  222. /// <remarks>
  223. /// <para>Use this method to prevent overwriting of an existing directory by default.</para>
  224. /// <para>This method does not work across disk volumes.</para>
  225. /// <para>Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method.</para>
  226. /// <para>If two directories have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior.</para>
  227. /// </remarks>
  228. /// </summary>
  229. /// <returns>A new <see cref="DirectoryInfo"/> instance if the directory was completely moved.</returns>
  230. /// <exception cref="ArgumentException"/>
  231. /// <exception cref="ArgumentNullException"/>
  232. /// <exception cref="DirectoryNotFoundException"/>
  233. /// <exception cref="IOException"/>
  234. /// <exception cref="NotSupportedException"/>
  235. /// <exception cref="UnauthorizedAccessException"/>
  236. /// <param name="destinationPath">
  237. /// <para>The name and path to which to move this directory.</para>
  238. /// <para>The destination cannot be another disk volume or a directory with the identical name.</para>
  239. /// <para>It can be an existing directory to which you want to add this directory as a subdirectory.</para>
  240. /// </param>
  241. /// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
  242. [SecurityCritical]
  243. public DirectoryInfo MoveTo(string destinationPath, PathFormat pathFormat)
  244. {
  245. string destinationPathLp;
  246. CopyToMoveToCore(destinationPath, null, MoveOptions.None, null, null, out destinationPathLp, pathFormat);
  247. return new DirectoryInfo(Transaction, destinationPathLp, PathFormat.LongFullPath);
  248. }
  249. /// <summary>[AlphaFS] Moves a <see cref="DirectoryInfo"/> instance and its contents to a new path, <see cref="MoveOptions"/> can be specified.
  250. /// <remarks>
  251. /// <para>Use this method to allow or prevent overwriting of an existing directory.</para>
  252. /// <para>This method does not work across disk volumes unless <paramref name="moveOptions"/> contains <see cref="MoveOptions.CopyAllowed"/>.</para>
  253. /// <para>Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method.</para>
  254. /// <para>If two directories have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior.</para>
  255. /// </remarks>
  256. /// </summary>
  257. /// <returns>A new <see cref="DirectoryInfo"/> instance if the directory was completely moved.</returns>
  258. /// <exception cref="ArgumentException"/>
  259. /// <exception cref="ArgumentNullException"/>
  260. /// <exception cref="DirectoryNotFoundException"/>
  261. /// <exception cref="IOException"/>
  262. /// <exception cref="NotSupportedException"/>
  263. /// <exception cref="UnauthorizedAccessException"/>
  264. /// <param name="destinationPath">
  265. /// <para>The name and path to which to move this directory.</para>
  266. /// <para>The destination cannot be another disk volume unless <paramref name="moveOptions"/> contains <see cref="MoveOptions.CopyAllowed"/>, or a directory with the identical name.</para>
  267. /// <para>It can be an existing directory to which you want to add this directory as a subdirectory.</para>
  268. /// </param>
  269. /// <param name="moveOptions"><see cref="MoveOptions"/> that specify how the directory is to be moved. This parameter can be <see langword="null"/>.</param>
  270. [SecurityCritical]
  271. public DirectoryInfo MoveTo(string destinationPath, MoveOptions moveOptions)
  272. {
  273. string destinationPathLp;
  274. CopyToMoveToCore(destinationPath, null, moveOptions, null, null, out destinationPathLp, PathFormat.RelativePath);
  275. return new DirectoryInfo(Transaction, destinationPathLp, PathFormat.LongFullPath);
  276. }
  277. /// <summary>[AlphaFS] Moves a <see cref="DirectoryInfo"/> instance and its contents to a new path, <see cref="MoveOptions"/> can be specified.
  278. /// <remarks>
  279. /// <para>Use this method to allow or prevent overwriting of an existing directory.</para>
  280. /// <para>This method does not work across disk volumes unless <paramref name="moveOptions"/> contains <see cref="MoveOptions.CopyAllowed"/>.</para>
  281. /// <para>Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method.</para>
  282. /// <para>If two directories have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior.</para>
  283. /// </remarks>
  284. /// </summary>
  285. /// <returns>A new <see cref="DirectoryInfo"/> instance if the directory was completely moved.</returns>
  286. /// <exception cref="ArgumentException"/>
  287. /// <exception cref="ArgumentNullException"/>
  288. /// <exception cref="DirectoryNotFoundException"/>
  289. /// <exception cref="IOException"/>
  290. /// <exception cref="NotSupportedException"/>
  291. /// <exception cref="UnauthorizedAccessException"/>
  292. /// <param name="destinationPath">
  293. /// <para>The name and path to which to move this directory.</para>
  294. /// <para>The destination cannot be another disk volume unless <paramref name="moveOptions"/> contains <see cref="MoveOptions.CopyAllowed"/>, or a directory with the identical name.</para>
  295. /// <para>It can be an existing directory to which you want to add this directory as a subdirectory.</para>
  296. /// </param>
  297. /// <param name="moveOptions"><see cref="MoveOptions"/> that specify how the directory is to be moved. This parameter can be <see langword="null"/>.</param>
  298. /// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
  299. [SecurityCritical]
  300. public DirectoryInfo MoveTo(string destinationPath, MoveOptions moveOptions, PathFormat pathFormat)
  301. {
  302. string destinationPathLp;
  303. CopyToMoveToCore(destinationPath, null, moveOptions, null, null, out destinationPathLp, pathFormat);
  304. return new DirectoryInfo(Transaction, destinationPathLp, PathFormat.LongFullPath);
  305. }
  306. /// <summary>[AlphaFS] Moves a <see cref="DirectoryInfo"/> instance and its contents to a new path, <see cref="MoveOptions"/> can be specified,
  307. /// <para>and the possibility of notifying the application of its progress through a callback function.</para>
  308. /// <remarks>
  309. /// <para>Use this method to allow or prevent overwriting of an existing directory.</para>
  310. /// <para>This method does not work across disk volumes unless <paramref name="moveOptions"/> contains <see cref="MoveOptions.CopyAllowed"/>.</para>
  311. /// <para>Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method.</para>
  312. /// <para>If two directories have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior.</para>
  313. /// </remarks>
  314. /// </summary>
  315. /// <returns>A <see cref="CopyMoveResult"/> class with details of the Move action.</returns>
  316. /// <exception cref="ArgumentException"/>
  317. /// <exception cref="ArgumentNullException"/>
  318. /// <exception cref="DirectoryNotFoundException"/>
  319. /// <exception cref="IOException"/>
  320. /// <exception cref="NotSupportedException"/>
  321. /// <exception cref="UnauthorizedAccessException"/>
  322. /// <param name="destinationPath">
  323. /// <para>The name and path to which to move this directory.</para>
  324. /// <para>The destination cannot be another disk volume unless <paramref name="moveOptions"/> contains <see cref="MoveOptions.CopyAllowed"/>, or a directory with the identical name.</para>
  325. /// <para>It can be an existing directory to which you want to add this directory as a subdirectory.</para>
  326. /// </param>
  327. /// <param name="moveOptions"><see cref="MoveOptions"/> that specify how the directory is to be moved. This parameter can be <see langword="null"/>.</param>
  328. /// <param name="progressHandler">A callback function that is called each time another portion of the directory has been moved. This parameter can be <see langword="null"/>.</param>
  329. /// <param name="userProgressData">The argument to be passed to the callback function. This parameter can be <see langword="null"/>.</param>
  330. [SecurityCritical]
  331. public CopyMoveResult MoveTo(string destinationPath, MoveOptions moveOptions, CopyMoveProgressRoutine progressHandler, object userProgressData)
  332. {
  333. string destinationPathLp;
  334. var cmr = CopyToMoveToCore(destinationPath, null, moveOptions, progressHandler, userProgressData, out destinationPathLp, PathFormat.RelativePath);
  335. CopyToMoveToCoreRefresh(destinationPath, destinationPathLp);
  336. return cmr;
  337. }
  338. /// <summary>[AlphaFS] Moves a <see cref="DirectoryInfo"/> instance and its contents to a new path, <see cref="MoveOptions"/> can be specified,
  339. /// <para>and the possibility of notifying the application of its progress through a callback function.</para>
  340. /// <remarks>
  341. /// <para>Use this method to allow or prevent overwriting of an existing directory.</para>
  342. /// <para>This method does not work across disk volumes unless <paramref name="moveOptions"/> contains <see cref="MoveOptions.CopyAllowed"/>.</para>
  343. /// <para>Whenever possible, avoid using short file names (such as XXXXXX~1.XXX) with this method.</para>
  344. /// <para>If two directories have equivalent short file names then this method may fail and raise an exception and/or result in undesirable behavior.</para>
  345. /// </remarks>
  346. /// </summary>
  347. /// <returns>A <see cref="CopyMoveResult"/> class with details of the Move action.</returns>
  348. /// <exception cref="ArgumentException"/>
  349. /// <exception cref="ArgumentNullException"/>
  350. /// <exception cref="DirectoryNotFoundException"/>
  351. /// <exception cref="IOException"/>
  352. /// <exception cref="NotSupportedException"/>
  353. /// <exception cref="UnauthorizedAccessException"/>
  354. /// <param name="destinationPath">
  355. /// <para>The name and path to which to move this directory.</para>
  356. /// <para>The destination cannot be another disk volume unless <paramref name="moveOptions"/> contains <see cref="MoveOptions.CopyAllowed"/>, or a directory with the identical name.</para>
  357. /// <para>It can be an existing directory to which you want to add this directory as a subdirectory.</para>
  358. /// </param>
  359. /// <param name="moveOptions"><see cref="MoveOptions"/> that specify how the directory is to be moved. This parameter can be <see langword="null"/>.</param>
  360. /// <param name="progressHandler">A callback function that is called each time another portion of the directory has been moved. This parameter can be <see langword="null"/>.</param>
  361. /// <param name="userProgressData">The argument to be passed to the callback function. This parameter can be <see langword="null"/>.</param>
  362. /// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
  363. [SecurityCritical]
  364. public CopyMoveResult MoveTo(string destinationPath, MoveOptions moveOptions, CopyMoveProgressRoutine progressHandler, object userProgressData, PathFormat pathFormat)
  365. {
  366. string destinationPathLp;
  367. var cmr = CopyToMoveToCore(destinationPath, null, moveOptions, progressHandler, userProgressData, out destinationPathLp, pathFormat);
  368. CopyToMoveToCoreRefresh(destinationPath, destinationPathLp);
  369. return cmr;
  370. }
  371. #endregion // AlphaFS
  372. #endregion // MoveTo
  373. #region Internal Methods
  374. /// <summary>Copy/move a Non-/Transacted file or directory including its children to a new location,
  375. /// <see cref="CopyOptions"/> or <see cref="MoveOptions"/> can be specified, and the possibility of notifying the application of its progress through a callback function.
  376. /// <remarks>
  377. /// <para>Option <see cref="CopyOptions.NoBuffering"/> is recommended for very large file transfers.</para>
  378. /// <para>You cannot use the Move method to overwrite an existing file, unless <paramref name="moveOptions"/> contains <see cref="MoveOptions.ReplaceExisting"/>.</para>
  379. /// <para>Note that if you attempt to replace a file by moving a file of the same name into that directory, you get an IOException.</para>
  380. /// </remarks>
  381. /// </summary>
  382. /// <returns>A <see cref="CopyMoveResult"/> class with details of the Copy or Move action.</returns>
  383. /// <exception cref="ArgumentException"/>
  384. /// <exception cref="ArgumentNullException"/>
  385. /// <exception cref="DirectoryNotFoundException"/>
  386. /// <exception cref="IOException"/>
  387. /// <exception cref="NotSupportedException"/>
  388. /// <exception cref="UnauthorizedAccessException"/>
  389. /// <param name="destinationPath">The destination directory path.</param>
  390. /// <param name="copyOptions"><see cref="CopyOptions"/> that specify how the file is to be copied. This parameter can be <see langword="null"/>.</param>
  391. /// <param name="moveOptions"><see cref="MoveOptions"/> that specify how the file is to be moved. This parameter can be <see langword="null"/>.</param>
  392. /// <param name="progressHandler">A callback function that is called each time another portion of the file has been copied. This parameter can be <see langword="null"/>.</param>
  393. /// <param name="userProgressData">The argument to be passed to the callback function. This parameter can be <see langword="null"/>.</param>
  394. /// <param name="longFullPath">Returns the retrieved long full path.</param>
  395. /// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
  396. [SecurityCritical]
  397. private CopyMoveResult CopyToMoveToCore(string destinationPath, CopyOptions? copyOptions, MoveOptions? moveOptions, CopyMoveProgressRoutine progressHandler, object userProgressData, out string longFullPath, PathFormat pathFormat)
  398. {
  399. var destinationPathLp = Path.GetExtendedLengthPathCore(null, destinationPath, pathFormat, GetFullPathOptions.TrimEnd | GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck);
  400. longFullPath = destinationPathLp;
  401. // Returns false when CopyMoveProgressResult is PROGRESS_CANCEL or PROGRESS_STOP.
  402. return Directory.CopyMoveCore(Transaction, LongFullName, destinationPathLp, copyOptions, moveOptions, progressHandler, userProgressData, null, PathFormat.LongFullPath);
  403. }
  404. private void CopyToMoveToCoreRefresh(string destinationPath, string destinationPathLp)
  405. {
  406. LongFullName = destinationPathLp;
  407. FullPath = Path.GetRegularPathCore(destinationPathLp, GetFullPathOptions.None, false);
  408. OriginalPath = destinationPath;
  409. DisplayPath = Path.GetRegularPathCore(OriginalPath, GetFullPathOptions.None, false);
  410. // Flush any cached information about the directory.
  411. Reset();
  412. }
  413. #endregion // Internal Methods
  414. }
  415. }