IFileSystemBindData实现不完全正常

时间:2015-10-28 14:49:52

标签: c# .net vb.net winapi

我正在使用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

1 个答案:

答案 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
相关问题