Advertisement
elektrohacker

FileSystemOperation class

Mar 30th, 2022
1,519
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
VB.NET 43.38 KB | None | 0 0
  1.     ''' ----------------------------------------------------------------------------------------------------
  2.     ''' <summary>
  3.     ''' Exposes methods to copy, move, rename, create, and delete single or multiple shell items at once.
  4.     ''' </summary>
  5.     ''' ----------------------------------------------------------------------------------------------------
  6.     ''' <remarks>
  7.     ''' <see href="https://github.com/misterhaan/au.Shared/tree/master/IO/Files.FileOperation"/>
  8.     ''' <para></para>
  9.     ''' <see href="https://github.com/mlaily/MSDNMagazine2007-.NET-Matters-IFileOperation-in-Windows-Vista"/>
  10.     ''' </remarks>
  11.     ''' ----------------------------------------------------------------------------------------------------
  12.     Public Class FileSystemOperation : Implements IDisposable
  13.  
  14. #Region " Private Fields "
  15.  
  16.         ''' <summary>
  17.         ''' The <see cref="IFileOperation"/> interface that exposes methods to
  18.         ''' copy, move, rename, create, and delete shell items.
  19.         ''' </summary>
  20.         Private ReadOnly fileOperation As IFileOperation
  21.  
  22.         ''' <summary>
  23.         ''' CLSID_FileOperation type.
  24.         ''' </summary>
  25.         Private ReadOnly fileOperationType As Type = Type.GetTypeFromCLSID(New Guid("3ad05575-8857-4850-9277-11b85bdb8e09"))
  26.  
  27. #End Region
  28.  
  29. #Region " Properties "
  30.  
  31.         ''' ----------------------------------------------------------------------------------------------------
  32.         ''' <summary>
  33.         ''' Gets or sets the flags that control the file operation
  34.         ''' when calling <see cref="FileSystemOperation.PerformOperations()"/> function.
  35.         ''' </summary>
  36.         ''' ----------------------------------------------------------------------------------------------------
  37.         ''' <value>
  38.         ''' The flags that control the file operation
  39.         ''' when <see cref="FileSystemOperation.PerformOperations()"/> function.
  40.         ''' </value>
  41.         ''' ----------------------------------------------------------------------------------------------------
  42.         Public Property OperationFlags() As FileOperationFlags
  43.             Get
  44.                 Return Me.operationFlags_
  45.             End Get
  46.             Set(value As FileOperationFlags)
  47.                 Me.operationFlags_ = value
  48.             End Set
  49.         End Property
  50.         ''' ----------------------------------------------------------------------------------------------------
  51.         ''' <summary>
  52.         ''' The flags that control the file operation
  53.         ''' when <see cref="FileSystemOperation.PerformOperations()"/> function.
  54.         ''' </summary>
  55.         ''' ----------------------------------------------------------------------------------------------------
  56.         Private operationFlags_ As FileOperationFlags =
  57.             FileOperationFlags.AddUndoRecord Or
  58.             FileOperationFlags.NoConfirmMakeDir
  59.  
  60.  
  61. #End Region
  62.  
  63. #Region " Constructors "
  64.  
  65.         ''' ----------------------------------------------------------------------------------------------------
  66.         ''' <summary>
  67.         ''' Initializes a new instance of the <see cref="FileSystemOperation"/> class.
  68.         ''' </summary>
  69.         ''' ----------------------------------------------------------------------------------------------------
  70.         Public Sub New()
  71.             Me.New(Nothing)
  72.         End Sub
  73.  
  74.         ''' ----------------------------------------------------------------------------------------------------
  75.         ''' <summary>
  76.         ''' Initializes a new instance of the <see cref="FileSystemOperation"/> class.
  77.         ''' </summary>
  78.         ''' ----------------------------------------------------------------------------------------------------
  79.         ''' <param name="owner">
  80.         ''' The parent or owner window for progress and dialog windows.
  81.         ''' </param>
  82.         ''' ----------------------------------------------------------------------------------------------------
  83.         Public Sub New(owner As IWin32Window)
  84.             Me.fileOperation = DirectCast(Activator.CreateInstance(Me.fileOperationType), IFileOperation)
  85.  
  86.             If owner IsNot Nothing Then
  87.                 Me.fileOperation.SetOwnerWindow(CUInt(owner.Handle))
  88.             End If
  89.         End Sub
  90.  
  91. #End Region
  92.  
  93. #Region " Public Methods "
  94.  
  95. #Region " Queue Copy "
  96.  
  97.         ''' ----------------------------------------------------------------------------------------------------
  98.         ''' <summary>
  99.         ''' Queues a copy operation of a source directory into its own directory.
  100.         ''' <para></para>
  101.         ''' </summary>
  102.         ''' ----------------------------------------------------------------------------------------------------
  103.         ''' <param name="srcDir">
  104.         ''' Source directory to copy into its own directory.
  105.         ''' </param>
  106.         '''
  107.         ''' <param name="newDirName">
  108.         ''' Gives a new name for the copied directory.
  109.         ''' <para></para>
  110.         ''' If null, the new directory name is the same as the source directory name.
  111.         ''' <para></para>
  112.         ''' Note that for directory duplication to take effect,
  113.         ''' the <see cref="FileSystemOperation.OperationFlags"/> property
  114.         ''' must have the <see cref="FileOperationFlags.RenameCollision"/> flag set
  115.         ''' before calling <see cref="FileSystemOperation.PerformOperations()"/> function.
  116.         ''' </param>  
  117.         ''' ----------------------------------------------------------------------------------------------------
  118.         <DebuggerStepThrough>
  119.         Public Sub QueueCopy(srcDir As DirectoryInfo, Optional newDirName As String = "")
  120.  
  121.             Me.QueueCopy(srcDir, srcDir.Parent, newDirName)
  122.  
  123.         End Sub
  124.  
  125.         ''' ----------------------------------------------------------------------------------------------------
  126.         ''' <summary>
  127.         ''' Queues a copy operation of a source directory to a destination directory.
  128.         ''' </summary>
  129.         ''' ----------------------------------------------------------------------------------------------------
  130.         ''' <param name="srcDir">
  131.         ''' Source directory to copy from.
  132.         ''' </param>
  133.         '''
  134.         ''' <param name="dstDir">
  135.         ''' Destination directory to copy to.
  136.         ''' </param>
  137.         '''
  138.         ''' <param name="newDirName">
  139.         ''' Gives a new name for the copied directory.
  140.         ''' <para></para>
  141.         ''' If null, the new directory name is the same as the source directory name.
  142.         ''' </param>        
  143.         ''' ----------------------------------------------------------------------------------------------------
  144.         <DebuggerStepThrough>
  145.         Public Sub QueueCopy(srcDir As DirectoryInfo, dstDir As DirectoryInfo, Optional newDirName As String = "")
  146.  
  147.             If srcDir Is Nothing Then
  148.                 Throw New ArgumentNullException(paramName:=NameOf(srcDir))
  149.             End If
  150.  
  151.             If Not srcDir.Exists Then
  152.                 Throw New DirectoryNotFoundException(message:=$"Source directory does not exist. ({srcDir.FullName})")
  153.             End If
  154.  
  155.             If dstDir Is Nothing Then
  156.                 Throw New ArgumentNullException(paramName:=NameOf(dstDir))
  157.             End If
  158.  
  159.             If Not dstDir.Exists Then
  160.                 Throw New DirectoryNotFoundException(message:=$"Destination directory does not exist. ({dstDir.FullName})")
  161.             End If
  162.  
  163.             Me.QueueCopy(srcDir.FullName, dstDir.FullName, newDirName)
  164.  
  165.         End Sub
  166.  
  167.         ''' ----------------------------------------------------------------------------------------------------
  168.         ''' <summary>
  169.         ''' Queues a copy operation of a source directory to a destination directory.
  170.         ''' </summary>
  171.         ''' ----------------------------------------------------------------------------------------------------
  172.         ''' <param name="srcDir">
  173.         ''' Source directory to copy from.
  174.         ''' </param>
  175.         '''
  176.         ''' <param name="dstDirPath">
  177.         ''' Destination directory path to copy to.
  178.         ''' </param>
  179.         '''
  180.         ''' <param name="newDirName">
  181.         ''' Gives a new name for the copied directory.
  182.         ''' <para></para>
  183.         ''' If null, the new directory name is the same as the source directory name.
  184.         ''' </param>        
  185.         ''' ----------------------------------------------------------------------------------------------------
  186.         <DebuggerStepThrough>
  187.         Public Sub QueueCopy(srcDir As DirectoryInfo, dstDirPath As String, Optional newDirName As String = "")
  188.             Me.QueueCopy(srcDir, New DirectoryInfo(dstDirPath), newDirName)
  189.         End Sub
  190.  
  191.         ''' ----------------------------------------------------------------------------------------------------
  192.         ''' <summary>
  193.         ''' Queues a copy operation of a source file into its own directory.
  194.         ''' </summary>
  195.         ''' ----------------------------------------------------------------------------------------------------
  196.         ''' <param name="srcFile">
  197.         ''' Source file to copy into its own directory.
  198.         ''' </param>
  199.         '''
  200.         ''' <param name="newFileName">
  201.         ''' Gives a new name for the copied file.
  202.         ''' <para></para>
  203.         ''' If null, the new file name is the same as the source file name.
  204.         ''' <para></para>
  205.         ''' Note that for file duplication to take effect,
  206.         ''' the <see cref="FileSystemOperation.OperationFlags"/> property
  207.         ''' must have the <see cref="FileOperationFlags.RenameCollision"/> flag set
  208.         ''' before calling <see cref="FileSystemOperation.PerformOperations()"/> function.
  209.         ''' </param>  
  210.         ''' ----------------------------------------------------------------------------------------------------
  211.         <DebuggerStepThrough>
  212.         Public Sub QueueCopy(srcFile As FileInfo, Optional newFileName As String = "")
  213.  
  214.             Me.QueueCopy(srcFile, srcFile.Directory, newFileName)
  215.  
  216.         End Sub
  217.  
  218.         ''' ----------------------------------------------------------------------------------------------------
  219.         ''' <summary>
  220.         ''' Queues a copy operation of a source file to a destination file.
  221.         ''' </summary>
  222.         ''' ----------------------------------------------------------------------------------------------------
  223.         ''' <param name="srcFile">
  224.         ''' Source file to copy from.
  225.         ''' </param>
  226.         '''
  227.         ''' <param name="dstFile">
  228.         ''' Destination file to copy to.
  229.         ''' </param>
  230.         ''' ----------------------------------------------------------------------------------------------------
  231.         <DebuggerStepThrough>
  232.         Public Sub QueueCopy(srcFile As FileInfo, dstFile As FileInfo)
  233.  
  234.             Me.QueueCopy(srcFile, dstFile?.Directory, dstFile?.Name)
  235.  
  236.         End Sub
  237.  
  238.         ''' ----------------------------------------------------------------------------------------------------
  239.         ''' <summary>
  240.         ''' Queues a copy operation of a source file to a destination directory.
  241.         ''' </summary>
  242.         ''' ----------------------------------------------------------------------------------------------------
  243.         ''' <param name="srcFile">
  244.         ''' Source file to copy from.
  245.         ''' </param>
  246.         '''
  247.         ''' <param name="dstDir">
  248.         ''' Destination directory to copy to.
  249.         ''' </param>
  250.         '''
  251.         ''' <param name="newFileName">
  252.         ''' Gives a new name for the copied file.
  253.         ''' <para></para>
  254.         ''' If null, the new file name is the same as the source file name.
  255.         ''' </param>
  256.         ''' ----------------------------------------------------------------------------------------------------
  257.         <DebuggerStepThrough>
  258.         Public Sub QueueCopy(srcFile As FileInfo, dstDir As DirectoryInfo, Optional newFileName As String = "")
  259.  
  260.             If srcFile Is Nothing Then
  261.                 Throw New ArgumentNullException(paramName:=NameOf(srcFile))
  262.             End If
  263.  
  264.             If Not srcFile.Exists Then
  265.                 Throw New FileNotFoundException(message:="Source file does not exist.", fileName:=srcFile.FullName)
  266.             End If
  267.  
  268.             If dstDir Is Nothing Then
  269.                 Throw New ArgumentNullException(paramName:=NameOf(dstDir))
  270.             End If
  271.  
  272.             If Not dstDir.Exists Then
  273.                 Throw New DirectoryNotFoundException(message:=$"Destination directory does not exist. ({dstDir.FullName})")
  274.             End If
  275.  
  276.             Me.QueueCopy(srcFile.FullName, dstDir.FullName, newFileName)
  277.  
  278.         End Sub
  279.  
  280.         ''' ----------------------------------------------------------------------------------------------------
  281.         ''' <summary>
  282.         ''' Queues a copy operation of a source file to a destination directory.
  283.         ''' </summary>
  284.         ''' ----------------------------------------------------------------------------------------------------
  285.         ''' <param name="srcFile">
  286.         ''' Source file to copy from.
  287.         ''' </param>
  288.         '''
  289.         ''' <param name="dstDirPath">
  290.         ''' Destination directory path to copy to.
  291.         ''' </param>
  292.         '''
  293.         ''' <param name="newFileName">
  294.         ''' Gives a new name for the copied file.
  295.         ''' <para></para>
  296.         ''' If null, the new file name is the same as the source file name.
  297.         ''' </param>
  298.         ''' ----------------------------------------------------------------------------------------------------
  299.         <DebuggerStepThrough>
  300.         Public Sub QueueCopy(srcFile As FileInfo, dstDirPath As String, Optional newFileName As String = "")
  301.  
  302.             Me.QueueCopy(srcFile, New DirectoryInfo(dstDirPath), newFileName)
  303.  
  304.         End Sub
  305.  
  306.         ''' ----------------------------------------------------------------------------------------------------
  307.         ''' <summary>
  308.         ''' Queues a copy operation of a source file or directory to a destination directory.
  309.         ''' </summary>
  310.         ''' ----------------------------------------------------------------------------------------------------
  311.         ''' <param name="srcItem">
  312.         ''' Full path to the source file or directory to copy from.
  313.         ''' </param>
  314.         '''
  315.         ''' <param name="dstDir">
  316.         ''' Destination directory to copy to.
  317.         ''' </param>
  318.         '''
  319.         ''' <param name="newItemName">
  320.         ''' Gives a new name for the copied item.
  321.         ''' <para></para>
  322.         ''' If null, the new item name is the same as the source item name.
  323.         ''' </param>
  324.         ''' ----------------------------------------------------------------------------------------------------
  325.         <DebuggerStepThrough>
  326.         Public Sub QueueCopy(srcItem As String, dstDir As DirectoryInfo, Optional newItemName As String = "")
  327.  
  328.             Me.QueueCopy(srcItem, dstDir?.FullName, newItemName)
  329.  
  330.         End Sub
  331.  
  332.         ''' ----------------------------------------------------------------------------------------------------
  333.         ''' <summary>
  334.         ''' Queues a copy operation of a source file or directory to a destination directory.
  335.         ''' </summary>
  336.         ''' ----------------------------------------------------------------------------------------------------
  337.         ''' <param name="srcItem">
  338.         ''' Full path to the source file or directory to copy from.
  339.         ''' </param>
  340.         '''
  341.         ''' <param name="dstDirPath">
  342.         ''' Destination directory path to copy to.
  343.         ''' </param>
  344.         '''
  345.         ''' <param name="newItemName">
  346.         ''' Gives a new name for the copied item.
  347.         ''' <para></para>
  348.         ''' If null, the new item name is the same as the source item name.
  349.         ''' </param>
  350.         ''' ----------------------------------------------------------------------------------------------------
  351.         <DebuggerStepThrough>
  352.         Public Sub QueueCopy(srcItem As String, dstDirPath As String, Optional newItemName As String = "")
  353.  
  354.             If String.IsNullOrWhiteSpace(srcItem) Then
  355.                 Throw New ArgumentNullException(paramName:=NameOf(srcItem))
  356.             End If
  357.  
  358.             If String.IsNullOrWhiteSpace(dstDirPath) Then
  359.                 Throw New ArgumentNullException(paramName:=NameOf(dstDirPath))
  360.             End If
  361.  
  362.             Using sourceItem As ComObjectDisposer(Of IShellItem) = Me.GetShellItem(srcItem),
  363.                   destinationDir As ComObjectDisposer(Of IShellItem) = Me.GetShellItem(dstDirPath)
  364.  
  365.                 If sourceItem.Value Is Nothing Then
  366.                     Throw New IOException(message:="Source file or directory does not exist.")
  367.                 End If
  368.  
  369.                 If destinationDir.Value Is Nothing Then
  370.                     Throw New IOException(message:="Destination directory does not exist.")
  371.                 End If
  372.  
  373.                 Me.fileOperation.SetOperationFlags(Me.operationFlags_)
  374.                 Me.fileOperation.CopyItem(sourceItem.Value, destinationDir.Value, newItemName, Nothing)
  375.             End Using
  376.  
  377.         End Sub
  378.  
  379. #End Region
  380.  
  381. #Region " Queue Move "
  382.  
  383.         ''' ----------------------------------------------------------------------------------------------------
  384.         ''' <summary>
  385.         ''' Queues a move operation of a source directory to a destination directory.
  386.         ''' </summary>
  387.         ''' ----------------------------------------------------------------------------------------------------
  388.         ''' <param name="srcDir">
  389.         ''' Source directory to move from.
  390.         ''' </param>
  391.         '''
  392.         ''' <param name="dstDir">
  393.         ''' Destination directory to move to.
  394.         ''' </param>
  395.         '''
  396.         ''' <param name="newDirName">
  397.         ''' Gives a new name for the moved directory.
  398.         ''' <para></para>
  399.         ''' If null, the new directory name is the same as the source directory name.
  400.         ''' </param>        
  401.         ''' ----------------------------------------------------------------------------------------------------
  402.         <DebuggerStepThrough>
  403.         Public Sub QueueMove(srcDir As DirectoryInfo, dstDir As DirectoryInfo, Optional newDirName As String = "")
  404.  
  405.             If srcDir Is Nothing Then
  406.                 Throw New ArgumentNullException(paramName:=NameOf(srcDir))
  407.             End If
  408.  
  409.             If Not srcDir.Exists Then
  410.                 Throw New DirectoryNotFoundException(message:=$"Source directory does not exist. ({srcDir.FullName})")
  411.             End If
  412.  
  413.             If dstDir Is Nothing Then
  414.                 Throw New ArgumentNullException(paramName:=NameOf(dstDir))
  415.             End If
  416.  
  417.             If Not dstDir.Exists Then
  418.                 Throw New DirectoryNotFoundException(message:=$"Destination directory does not exist. ({dstDir.FullName})")
  419.             End If
  420.  
  421.             Me.QueueMove(srcDir.FullName, dstDir.FullName, newDirName)
  422.  
  423.         End Sub
  424.  
  425.         ''' ----------------------------------------------------------------------------------------------------
  426.         ''' <summary>
  427.         ''' Queues a move operation of a source directory to a destination directory.
  428.         ''' </summary>
  429.         ''' ----------------------------------------------------------------------------------------------------
  430.         ''' <param name="srcDir">
  431.         ''' Source directory to move from.
  432.         ''' </param>
  433.         '''
  434.         ''' <param name="dstDirPath">
  435.         ''' Destination directory path to move to.
  436.         ''' </param>
  437.         '''
  438.         ''' <param name="newDirName">
  439.         ''' Gives a new name for the moved directory.
  440.         ''' <para></para>
  441.         ''' If null, the new directory name is the same as the source directory name.
  442.         ''' </param>        
  443.         ''' ----------------------------------------------------------------------------------------------------
  444.         <DebuggerStepThrough>
  445.         Public Sub QueueMove(srcDir As DirectoryInfo, dstDirPath As String, Optional newDirName As String = "")
  446.             Me.QueueMove(srcDir, New DirectoryInfo(dstDirPath), newDirName)
  447.         End Sub
  448.  
  449.         ''' ----------------------------------------------------------------------------------------------------
  450.         ''' <summary>
  451.         ''' Queues a move operation of a source file to a destination file.
  452.         ''' </summary>
  453.         ''' ----------------------------------------------------------------------------------------------------
  454.         ''' <param name="srcFile">
  455.         ''' Source file to move from.
  456.         ''' </param>
  457.         '''
  458.         ''' <param name="dstFile">
  459.         ''' Destination file to move to.
  460.         ''' </param>
  461.         ''' ----------------------------------------------------------------------------------------------------
  462.         <DebuggerStepThrough>
  463.         Public Sub QueueMove(srcFile As FileInfo, dstFile As FileInfo)
  464.  
  465.             Me.QueueMove(srcFile, dstFile?.Directory, dstFile?.Name)
  466.  
  467.         End Sub
  468.  
  469.         ''' ----------------------------------------------------------------------------------------------------
  470.         ''' <summary>
  471.         ''' Queues a move operation of a source file to a destination directory.
  472.         ''' </summary>
  473.         ''' ----------------------------------------------------------------------------------------------------
  474.         ''' <param name="srcFile">
  475.         ''' Source file to move from.
  476.         ''' </param>
  477.         '''
  478.         ''' <param name="dstDir">
  479.         ''' Destination directory to move to.
  480.         ''' </param>
  481.         '''
  482.         ''' <param name="newFileName">
  483.         ''' Gives a new name for the moved file.
  484.         ''' <para></para>
  485.         ''' If null, the new file name is the same as the source file name.
  486.         ''' </param>
  487.         ''' ----------------------------------------------------------------------------------------------------
  488.         <DebuggerStepThrough>
  489.         Public Sub QueueMove(srcFile As FileInfo, dstDir As DirectoryInfo, Optional newFileName As String = "")
  490.  
  491.             If srcFile Is Nothing Then
  492.                 Throw New ArgumentNullException(paramName:=NameOf(srcFile))
  493.             End If
  494.  
  495.             If Not srcFile.Exists Then
  496.                 Throw New FileNotFoundException(message:="Source file does not exist.", fileName:=srcFile.FullName)
  497.             End If
  498.  
  499.             If dstDir Is Nothing Then
  500.                 Throw New ArgumentNullException(paramName:=NameOf(dstDir))
  501.             End If
  502.  
  503.             If Not dstDir.Exists Then
  504.                 Throw New DirectoryNotFoundException(message:=$"Destination directory does not exist. ({dstDir.FullName})")
  505.             End If
  506.  
  507.             Me.QueueMove(srcFile.FullName, dstDir.FullName, newFileName)
  508.  
  509.         End Sub
  510.  
  511.         ''' ----------------------------------------------------------------------------------------------------
  512.         ''' <summary>
  513.         ''' Queues a move operation of a source file to a destination directory.
  514.         ''' </summary>
  515.         ''' ----------------------------------------------------------------------------------------------------
  516.         ''' <param name="srcFile">
  517.         ''' Source file to move from.
  518.         ''' </param>
  519.         '''
  520.         ''' <param name="dstDirPath">
  521.         ''' Destination directory path to move to.
  522.         ''' </param>
  523.         '''
  524.         ''' <param name="newFileName">
  525.         ''' Gives a new name for the moved file.
  526.         ''' <para></para>
  527.         ''' If null, the new file name is the same as the source file name.
  528.         ''' </param>
  529.         ''' ----------------------------------------------------------------------------------------------------
  530.         <DebuggerStepThrough>
  531.         Public Sub QueueMove(srcFile As FileInfo, dstDirPath As String, Optional newFileName As String = "")
  532.  
  533.             Me.QueueMove(srcFile, New DirectoryInfo(dstDirPath), newFileName)
  534.  
  535.         End Sub
  536.  
  537.         ''' ----------------------------------------------------------------------------------------------------
  538.         ''' <summary>
  539.         ''' Queues a move operation of a source file or directory to a destination directory.
  540.         ''' </summary>
  541.         ''' ----------------------------------------------------------------------------------------------------
  542.         ''' <param name="srcItem">
  543.         ''' Full path to the source file or directory to move from.
  544.         ''' </param>
  545.         '''
  546.         ''' <param name="dstDir">
  547.         ''' Destination directory to move to.
  548.         ''' </param>
  549.         '''
  550.         ''' <param name="newItemName">
  551.         ''' Gives a new name for the moved item.
  552.         ''' <para></para>
  553.         ''' If null, the new item name is the same as the source item name.
  554.         ''' </param>
  555.         ''' ----------------------------------------------------------------------------------------------------
  556.         <DebuggerStepThrough>
  557.         Public Sub QueueMove(srcItem As String, dstDir As DirectoryInfo, Optional newItemName As String = "")
  558.  
  559.             Me.QueueMove(srcItem, dstDir?.FullName, newItemName)
  560.  
  561.         End Sub
  562.  
  563.         ''' ----------------------------------------------------------------------------------------------------
  564.         ''' <summary>
  565.         ''' Queues a move operation of a source file or directory to a destination directory.
  566.         ''' </summary>
  567.         ''' ----------------------------------------------------------------------------------------------------
  568.         ''' <param name="srcItem">
  569.         ''' Full path to the source file or directory to move from.
  570.         ''' </param>
  571.         '''
  572.         ''' <param name="dstDirPath">
  573.         ''' Destination directory path to move to.
  574.         ''' </param>
  575.         '''
  576.         ''' <param name="newItemName">
  577.         ''' Gives a new name for the moved item.
  578.         ''' <para></para>
  579.         ''' If null, the new item name is the same as the source item name.
  580.         ''' </param>
  581.         ''' ----------------------------------------------------------------------------------------------------
  582.         <DebuggerStepThrough>
  583.         Public Sub QueueMove(srcItem As String, dstDirPath As String, Optional newItemName As String = "")
  584.  
  585.             If String.IsNullOrWhiteSpace(srcItem) Then
  586.                 Throw New ArgumentNullException(paramName:=NameOf(srcItem))
  587.             End If
  588.  
  589.             If String.IsNullOrWhiteSpace(dstDirPath) Then
  590.                 Throw New ArgumentNullException(paramName:=NameOf(dstDirPath))
  591.             End If
  592.  
  593.             Using sourceItem As ComObjectDisposer(Of IShellItem) = Me.GetShellItem(srcItem),
  594.                   destinationDir As ComObjectDisposer(Of IShellItem) = Me.GetShellItem(dstDirPath)
  595.  
  596.                 If sourceItem.Value Is Nothing Then
  597.                     Throw New IOException(message:="Source file or directory does not exist.")
  598.                 End If
  599.  
  600.                 If destinationDir.Value Is Nothing Then
  601.                     Throw New IOException(message:="Destination directory does not exist.")
  602.                 End If
  603.  
  604.                 Me.fileOperation.SetOperationFlags(Me.operationFlags_)
  605.                 Me.fileOperation.MoveItem(sourceItem.Value, destinationDir.Value, newItemName, Nothing)
  606.             End Using
  607.  
  608.         End Sub
  609.  
  610. #End Region
  611.  
  612. #Region " Queue Rename "
  613.  
  614.         ''' ----------------------------------------------------------------------------------------------------
  615.         ''' <summary>
  616.         ''' Queues a rename operation for a directory.
  617.         ''' <para></para>
  618.         ''' </summary>
  619.         ''' ----------------------------------------------------------------------------------------------------
  620.         ''' <param name="dir">
  621.         ''' Directory to rename.
  622.         ''' </param>
  623.         '''
  624.         ''' <param name="newDirName">
  625.         ''' Gives a new name for the directory.
  626.         ''' </param>  
  627.         ''' ----------------------------------------------------------------------------------------------------
  628.         <DebuggerStepThrough>
  629.         Public Sub QueueRename(dir As DirectoryInfo, newDirName As String)
  630.  
  631.             Me.QueueRename(dir?.FullName, newDirName)
  632.  
  633.         End Sub
  634.  
  635.         ''' ----------------------------------------------------------------------------------------------------
  636.         ''' <summary>
  637.         ''' Queues a rename operation for a file.
  638.         ''' </summary>
  639.         ''' ----------------------------------------------------------------------------------------------------
  640.         ''' <param name="file">
  641.         ''' File to rename.
  642.         ''' </param>
  643.         '''
  644.         ''' <param name="newFileName">
  645.         ''' Gives a new name for the file.
  646.         ''' </param>  
  647.         '''
  648.         ''' <param name="newFileExtension">
  649.         ''' Optionally, gives a new extension for the file.
  650.         ''' </param>  
  651.         ''' ----------------------------------------------------------------------------------------------------
  652.         <DebuggerStepThrough>
  653.         Public Sub QueueRename(file As FileInfo, newFileName As String, Optional newFileExtension As String = "")
  654.  
  655.             Me.QueueRename(file?.FullName, newFileName, newFileExtension)
  656.  
  657.         End Sub
  658.  
  659.         ''' ----------------------------------------------------------------------------------------------------
  660.         ''' <summary>
  661.         ''' Queues a rename operation for a file or directory.
  662.         ''' </summary>
  663.         ''' ----------------------------------------------------------------------------------------------------
  664.         ''' <param name="item">
  665.         ''' Full path to the file or directory to rename.
  666.         ''' </param>
  667.         '''
  668.         ''' <param name="newItemName">
  669.         ''' Gives a new name for the file or directory.
  670.         ''' </param>
  671.         '''
  672.         ''' <param name="newFileExtension">
  673.         ''' Optionally, and if the item is a file, gives a new extension to it.
  674.         ''' </param>
  675.         ''' ----------------------------------------------------------------------------------------------------
  676.         <DebuggerStepThrough>
  677.         Public Sub QueueRename(item As String, newItemName As String, Optional newFileExtension As String = "")
  678.  
  679.             If String.IsNullOrWhiteSpace(item) Then
  680.                 Throw New ArgumentNullException(paramName:=NameOf(item))
  681.             End If
  682.  
  683.             newFileExtension = newFileExtension.TrimStart(". ".ToCharArray())
  684.  
  685.             If File.Exists(item) AndAlso Not String.IsNullOrWhiteSpace(newFileExtension) Then
  686.                 Me.QueueMove(item, Path.GetDirectoryName(item), $"{newItemName}.{newFileExtension}")
  687.  
  688.             Else
  689.                 Using sourceItem As ComObjectDisposer(Of IShellItem) = Me.GetShellItem(item)
  690.                     If sourceItem.Value Is Nothing Then
  691.                         Throw New IOException(message:="File or directory does not exist.")
  692.                     End If
  693.  
  694.                     Me.fileOperation.SetOperationFlags(Me.operationFlags_)
  695.                     Me.fileOperation.RenameItem(sourceItem.Value, newItemName, Nothing)
  696.                 End Using
  697.  
  698.             End If
  699.  
  700.         End Sub
  701.  
  702. #End Region
  703.  
  704. #Region " Queue Create "
  705.  
  706.         ''' ----------------------------------------------------------------------------------------------------
  707.         ''' <summary>
  708.         ''' Queues a create operation for a directory.
  709.         ''' </summary>
  710.         ''' ----------------------------------------------------------------------------------------------------
  711.         ''' <param name="newDir">
  712.         ''' Directory to create.
  713.         ''' </param>
  714.         '''
  715.         ''' <param name="attribs">
  716.         ''' Optionally, gives the specified attributes to the created directory.
  717.         ''' </param>  
  718.         ''' ----------------------------------------------------------------------------------------------------
  719.         <DebuggerStepThrough>
  720.         Public Sub QueueCreate(newDir As DirectoryInfo,
  721.                                Optional attribs As FileAttributes = FileAttributes.Normal Or
  722.                                                                     FileAttributes.Directory)
  723.  
  724.             Me.QueueCreate(newDir?.Parent?.FullName, newDir?.FullName, attribs)
  725.  
  726.         End Sub
  727.  
  728.         ''' ----------------------------------------------------------------------------------------------------
  729.         ''' <summary>
  730.         ''' Queues a create operation for a file.
  731.         ''' </summary>
  732.         ''' ----------------------------------------------------------------------------------------------------
  733.         ''' <param name="newFile">
  734.         ''' File to create.
  735.         ''' </param>
  736.         '''
  737.         ''' <param name="attribs">
  738.         ''' Optionally, gives the specified attributes to the created file.
  739.         ''' </param>  
  740.         ''' ----------------------------------------------------------------------------------------------------
  741.         <DebuggerStepThrough>
  742.         Public Sub QueueCreate(newFile As FileInfo, Optional attribs As FileAttributes = FileAttributes.Normal)
  743.  
  744.             Me.QueueCreate(newFile?.Directory?.FullName, newFile?.FullName, attribs)
  745.  
  746.         End Sub
  747.  
  748.         ''' ----------------------------------------------------------------------------------------------------
  749.         ''' <summary>
  750.         ''' Queues a create operation for a file or directory.
  751.         ''' </summary>
  752.         ''' ----------------------------------------------------------------------------------------------------
  753.         ''' <param name="dstDirPath">
  754.         ''' Destination directory path to create the file or directory.
  755.         ''' </param>
  756.         '''
  757.         ''' <param name="newItemName">
  758.         ''' File or directory to create.
  759.         ''' <para></para>
  760.         ''' To create a directory, you must set the <see cref="FileAttributes.Directory"/> flag
  761.         ''' in <paramref name="attribs"/> parameter.
  762.         ''' </param>
  763.         '''
  764.         ''' <param name="attribs">
  765.         ''' Optionally, gives the specified attributes to the created file or directory.
  766.         ''' </param>  
  767.         ''' ----------------------------------------------------------------------------------------------------
  768.         <DebuggerStepThrough>
  769.         Public Sub QueueCreate(dstDirPath As String, newItemName As String,
  770.                                Optional attribs As FileAttributes = FileAttributes.Normal)
  771.  
  772.             If String.IsNullOrWhiteSpace(dstDirPath) Then
  773.                 Throw New ArgumentNullException(paramName:=NameOf(dstDirPath))
  774.             End If
  775.  
  776.             If String.IsNullOrWhiteSpace(newItemName) Then
  777.                 Throw New ArgumentNullException(paramName:=NameOf(newItemName))
  778.             End If
  779.  
  780.             Using destinationDir As ComObjectDisposer(Of IShellItem) = Me.GetShellItem(dstDirPath)
  781.  
  782.                 If destinationDir.Value Is Nothing Then
  783.                     Throw New IOException(message:="Destination directory does not exist.")
  784.                 End If
  785.  
  786.                 Me.fileOperation.SetOperationFlags(Me.operationFlags_)
  787.                 Me.fileOperation.NewItem(destinationDir.Value, attribs, newItemName, Nothing, Nothing)
  788.             End Using
  789.  
  790.         End Sub
  791.  
  792. #End Region
  793.  
  794. #Region " Queue Delete "
  795.  
  796.         ''' ----------------------------------------------------------------------------------------------------
  797.         ''' <summary>
  798.         ''' Queues a delete operation for a directory.
  799.         ''' <para></para>
  800.         ''' </summary>
  801.         ''' ----------------------------------------------------------------------------------------------------
  802.         ''' <param name="dir">
  803.         ''' Directory to delete.
  804.         ''' </param>
  805.         ''' ----------------------------------------------------------------------------------------------------
  806.         <DebuggerStepThrough>
  807.         Public Sub QueueDelete(dir As DirectoryInfo)
  808.  
  809.             Me.QueueDelete(dir?.FullName)
  810.  
  811.         End Sub
  812.  
  813.         ''' ----------------------------------------------------------------------------------------------------
  814.         ''' <summary>
  815.         ''' Queues a delete operation for a file.
  816.         ''' </summary>
  817.         ''' ----------------------------------------------------------------------------------------------------
  818.         ''' <param name="file">
  819.         ''' File to delete.
  820.         ''' </param>
  821.         ''' ----------------------------------------------------------------------------------------------------
  822.         <DebuggerStepThrough>
  823.         Public Sub QueueDelete(file As FileInfo)
  824.  
  825.             Me.QueueDelete(file?.FullName)
  826.  
  827.         End Sub
  828.  
  829.         ''' ----------------------------------------------------------------------------------------------------
  830.         ''' <summary>
  831.         ''' Queues a delete operation for a file or directory.
  832.         ''' </summary>
  833.         ''' ----------------------------------------------------------------------------------------------------
  834.         ''' <param name="item">
  835.         ''' Full path to the file or directory to delete.
  836.         ''' </param>
  837.         ''' ----------------------------------------------------------------------------------------------------
  838.         <DebuggerStepThrough>
  839.         Public Sub QueueDelete(item As String)
  840.  
  841.             If String.IsNullOrWhiteSpace(item) Then
  842.                 Throw New ArgumentNullException(paramName:=NameOf(item))
  843.             End If
  844.  
  845.             Using sourceItem As ComObjectDisposer(Of IShellItem) = Me.GetShellItem(item)
  846.                 If sourceItem.Value Is Nothing Then
  847.                     Throw New IOException(message:="File or directory does not exist.")
  848.                 End If
  849.  
  850.                 Me.fileOperation.SetOperationFlags(Me.operationFlags_)
  851.                 Me.fileOperation.DeleteItem(sourceItem.Value, Nothing)
  852.             End Using
  853.  
  854.         End Sub
  855.  
  856. #End Region
  857.  
  858. #Region " Other "
  859.  
  860.         ''' ----------------------------------------------------------------------------------------------------
  861.         ''' <summary>
  862.         ''' Executes all the queued operations.
  863.         ''' </summary>
  864.         ''' ----------------------------------------------------------------------------------------------------
  865.         ''' <returns>
  866.         ''' If this method succeeds, it returns <see cref="HResult.S_OK"/>.
  867.         ''' Otherwise, it returns an <see cref="HResult"/> error code.
  868.         ''' <para></para>
  869.         ''' Note that if the operation was canceled by the user, this method can still return a success code.
  870.         ''' <para></para>
  871.         ''' Use the <see cref="FileSystemOperation.GetAnyOperationsAborted"/> function to determine if this was the case.
  872.         '''</returns>
  873.         ''' ----------------------------------------------------------------------------------------------------
  874.         <DebuggerStepThrough>
  875.         Public Function PerformOperations() As HResult
  876.  
  877.             Dim result As HResult = HResult.S_OK
  878.             Try
  879.                 result = Me.fileOperation.PerformOperations()
  880.             Catch ex As Exception
  881.                 ' If something goes wrong the IFileOperation UI will tell the user so we don't have to.
  882.             End Try
  883.  
  884.             Return result
  885.  
  886.         End Function
  887.  
  888.         ''' ----------------------------------------------------------------------------------------------------
  889.         ''' <summary>
  890.         ''' Gets a value that states whether any file operations initiated
  891.         ''' by a call to <see cref="FileSystemOperation.PerformOperations()"/> were stopped before they were complete.
  892.         ''' <para></para>
  893.         ''' The operations could be stopped either by user action or silently by the system.
  894.         ''' </summary>
  895.         ''' ----------------------------------------------------------------------------------------------------
  896.         ''' <returns>
  897.         ''' <see langword="True"/> if any file operations were aborted before they were complete;
  898.         ''' otherwise, <see langword="False"/>.
  899.         ''' </returns>
  900.         ''' ----------------------------------------------------------------------------------------------------
  901.         <DebuggerStepThrough>
  902.         Public Function GetAnyOperationsAborted() As Boolean
  903.             Dim result As Boolean
  904.             Me.fileOperation.GetAnyOperationsAborted(result)
  905.             Return result
  906.         End Function
  907.  
  908. #End Region
  909.  
  910. #End Region
  911.  
  912. #Region " Private Methods "
  913.  
  914.         ''' ----------------------------------------------------------------------------------------------------
  915.         ''' <summary>
  916.         ''' Converts a file or directory path to <see cref="IShellItem"/>.
  917.         ''' </summary>
  918.         ''' ----------------------------------------------------------------------------------------------------
  919.         ''' <param name="itemPath">
  920.         ''' The source file or directory path.
  921.         ''' </param>
  922.         ''' ----------------------------------------------------------------------------------------------------
  923.         ''' <returns>
  924.         ''' The resulting <see cref="ComObjectDisposer(Of IShellItem)"/>.
  925.         ''' </returns>
  926.         ''' ----------------------------------------------------------------------------------------------------
  927.         <DebuggerStepThrough>
  928.         Private Function GetShellItem(itemPath As String) As ComObjectDisposer(Of IShellItem)
  929.             Dim shellItem As IShellItem = Nothing
  930.             NativeMethods.SHCreateItemFromParsingName(itemPath, IntPtr.Zero, GetType(IShellItem).GUID, shellItem)
  931.             Return New ComObjectDisposer(Of IShellItem)(shellItem)
  932.         End Function
  933.  
  934. #End Region
  935.  
  936. #Region " IDisposable Implementation "
  937.  
  938.         ''' ----------------------------------------------------------------------------------------------------
  939.         ''' <summary>
  940.         ''' Flag to detect redundant calls when disposing.
  941.         ''' </summary>
  942.         ''' ----------------------------------------------------------------------------------------------------
  943.         Private isDisposed As Boolean = False
  944.  
  945.         ''' ----------------------------------------------------------------------------------------------------
  946.         ''' <summary>
  947.         ''' Releases all the resources used by this instance.
  948.         ''' </summary>
  949.         ''' ----------------------------------------------------------------------------------------------------
  950.         <DebuggerStepThrough>
  951.         Public Sub Dispose() Implements IDisposable.Dispose
  952.             Me.Dispose(isDisposing:=True)
  953.         End Sub
  954.  
  955.         ''' ----------------------------------------------------------------------------------------------------
  956.         ''' <summary>
  957.         ''' Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
  958.         ''' Releases unmanaged and, optionally, managed resources.
  959.         ''' </summary>
  960.         ''' ----------------------------------------------------------------------------------------------------
  961.         ''' <param name="isDisposing">
  962.         ''' <see langword="True"/>  to release both managed and unmanaged resources;
  963.         ''' <see langword="False"/> to release only unmanaged resources.
  964.         ''' </param>
  965.         ''' ----------------------------------------------------------------------------------------------------
  966.         <DebuggerStepThrough>
  967.         Protected Overridable Sub Dispose(isDisposing As Boolean)
  968.  
  969.             If (Not Me.isDisposed) AndAlso isDisposing Then
  970.  
  971.                 If Me.fileOperation IsNot Nothing Then
  972.                     Marshal.FinalReleaseComObject(Me.fileOperation)
  973.                     GC.SuppressFinalize(Me)
  974.                 End If
  975.  
  976.             End If
  977.  
  978.             Me.isDisposed = True
  979.  
  980.         End Sub
  981.  
  982. #End Region
  983.  
  984.     End Class
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement