我正在使用IFileOperation(Windows shell)API来批量复制/删除文件。到目前为止一切都很好但是,将文件复制/移动到目前尚不存在的目标会稍微复杂一些 - 您需要使用IFileSystemBindData接口为目标创建一个shell项。它工作 - 间歇性。其他时候它会在IfileOperation.MoveItem方法中引发异常。
欢迎任何建议。
注意:
接口:
Namespace Shell
<ComImport> _
<Guid("01E18D10-4D8B-11d2-855D-006008059367")> _
<InterfaceType(ComInterfaceType.InterfaceIsIUnknown)> _
Public Interface IFileSystemBindData
Function GetFindData(ByRef wfd As WIN32_FIND_DATA) As UInteger
Function SetFindData(ByRef wfd As WIN32_FIND_DATA) As UInteger
End Interface
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _
Public Structure WIN32_FIND_DATA
Public dwFileAttributes As UInteger
Public ftCreationTime As System.Runtime.InteropServices.ComTypes.FILETIME
Public ftLastAccessTime As System.Runtime.InteropServices.ComTypes.FILETIME
Public ftLastWriteTime As System.Runtime.InteropServices.ComTypes.FILETIME
Public nFileSizeHigh As UInteger
Public nFileSizeLow As UInteger
Public dwReserved0 As UInteger
Public dwReserved1 As UInteger
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=260)> Public cFileName As String
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=14)> Public cAlternateFileName As String
End Structure
End Namespace
实现:
Namespace Shell
Public Class FileSystemBindData
Implements IFileSystemBindData
Dim wf As WIN32_FIND_DATA
Public Function GetFindData(ByRef pfd As WIN32_FIND_DATA) As UInteger Implements IFileSystemBindData.GetFindData
pfd = wf
Return 0
End Function
Public Function SetFindData(ByVal pfd As WIN32_FIND_DATA) As UInteger Implements IFileSystemBindData.SetFindData
wf = pfd
Return 0
End Function
<DllImport("ole32.dll")> _
Public Shared Function CreateBindCtx(reserved As UInteger, ByRef ppbc As IBindCtx) As Integer
End Function
End Class
End Namespace
创建绑定上下文:
Dim wfd As New WIN32_FIND_DATA
wfd.dwFileAttributes = &H10 'FILE_ATTRIBUTE_DIRECTORY'
fsbd.SetFindData(wfd)
Const STR_FILE_SYS_BIND_DATA As String = "File System Bind Data"
FileSystemBindData.CreateBindCtx(0, bc)
bc.RegisterObjectParam(STR_FILE_SYS_BIND_DATA, fsbd)
创建具有目标和绑定上下文的shell项的函数 -
Private Function CreateShellItemNew(destination As String) As ComReleaser(Of IShellItem)
Return New ComReleaser(Of IShellItem)(DirectCast(SHCreateItemFromParsingName(destination, bc, _shellItemGuid), IShellItem))
End Function
此处调用的函数。它抛出MoveItem行“值不在预期范围内”
Public Sub MoveItemCreateDest(source As String, destination As String, newName As String)
ThrowIfDisposed()
Try
Using sourceItem As ComReleaser(Of IShellItem) = CreateShellItem(source)
Using destinationItem As ComReleaser(Of IShellItem) = CreateShellItemNew(destination)
_fileOperation.MoveItem(sourceItem.Item, destinationItem.Item, newName, Nothing)
End Using
End Using
Catch ex As Exception
MsgBox("Moveitem error: " & ex.Message)
End Try
End Sub
答案 0 :(得分:0)
解决它 - 在界面中以其他方式翻转函数的顺序并正确调用它们。之前由于函数被反转而发生数据损坏(Set调用而不是Get)。我不知道COM接口中的函数顺序有效。
<ComImport()> _
<InterfaceType(ComInterfaceType.InterfaceIsIUnknown)> _
<Guid("01E18D10-4D8B-11d2-855D-006008059367")> _
Public Interface IFileSystemBindData
<PreserveSig()> Function SetFindData(ByVal pfd As WIN32_FIND_DATA) As <MarshalAs(UnmanagedType.Error)> Integer
<PreserveSig()> Function GetFindData(<Out()> ByRef pfd As WIN32_FIND_DATA) As <MarshalAs(UnmanagedType.Error)> Integer
End Interface