callbacks in vb.net and c# using copyfileex

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

I have been trying to code a callback in vb.net using the delegate method. I
have successfully compiled the program and run it but after it accessess the
copyfileex winapi method and then calls the callback method there are
problems. For one the data that is populated in the parameters is wrong. I am
expecting a value of 0 , 1 or maybe 2 for the dwcallbackreason and I get some
outrageous number like 10788264 which incidentally is the same each time I
run it, even on different machines. If that were not enough the callback
method once it completes and returns, returns back into itself. At that point
it goes through one more time and then dies. Now I thought there might be a
bug or something since all the code I had referenced on the subject is close
to mine and I have seen other comments regarding not being able to get this
to work so I re-coded it in C# just to check.
In C# the code behaves slightly better in that the numbers coming in for
the dwcallback reason are what I expect, a 0 for the dwcallback reason but
the method still calls itself again. Any help would be greatly appreciated. I
will post code for a reference if needed.

This all worked fine in vb6.
 
I have been trying to code a callback in vb.net using the delegate method. I
have successfully compiled the program and run it but after it accessess the
copyfileex winapi method and then calls the callback method there are
problems. For one the data that is populated in the parameters is wrong. I am
expecting a value of 0 , 1 or maybe 2 for the dwcallbackreason and I get some
outrageous number like 10788264 which incidentally is the same each time I
run it, even on different machines. If that were not enough the callback
method once it completes and returns, returns back into itself. At that point
it goes through one more time and then dies. Now I thought there might be a
bug or something since all the code I had referenced on the subject is close
to mine and I have seen other comments regarding not being able to get this
to work so I re-coded it in C# just to check.
In C# the code behaves slightly better in that the numbers coming in for
the dwcallback reason are what I expect, a 0 for the dwcallback reason but
the method still calls itself again. Any help would be greatly appreciated. I
will post code for a reference if needed.

This all worked fine in vb6.

Post the code....
 
Here is the C# code - the VB.net codee is below - It is kinda long

Imports System.Runtime.InteropServices

Module Module1
Public Const PROGRESS_CONTINUE As Integer = 0
Public Const PROGRESS_CANCEL As Integer = 1
Public Const PROGRESS_STOP As Integer = 2
Public Const PROGRESS_QUIET As Integer = 3

'CopyFileEx callback routine state change values
Public Const CALLBACK_CHUNK_FINISHED As Integer = &H0S
Public Const CALLBACK_STREAM_SWITCH As Integer = &H1S

'CopyFileEx option flags
Public Const COPY_FILE_FAIL_IF_EXISTS As Integer = &H1S
Public Const COPY_FILE_RESTARTABLE As Integer = &H2S
Public Const COPY_FILE_OPEN_SOURCE_FOR_WRITE As Integer = &H4S

Public Declare Auto Function CopyFileEx Lib "kernel32" _
(ByVal lpExistingFileName As String, ByVal lpNewFileName As String, _
ByVal lpProgressRoutine As CPCallback, ByVal lpData As Long, ByVal
pbCancel As Boolean, _
ByVal dwCopyFlags As Integer) As Integer

Public Delegate Function CPCallback(ByVal TotalFileSize As Decimal, _
ByVal TotalBytesTransferred As Decimal, ByVal StreamSize As
Decimal, _
ByVal StreamBytesTransferred As Decimal, ByVal dwStreamNumber As
Integer, _
ByVal dwCallbackReason As Integer, ByVal hSourceFile As Integer, _
ByVal hDestinationFile As Integer, ByRef lpData As Integer) As
Integer

Public Function CopyProgressCallback(ByVal TotalFileSize As Decimal, _
ByVal TotalBytesTransferred As Decimal, ByVal StreamSize As
Decimal, _
ByVal StreamBytesTransferred As Decimal, ByVal dwStreamNumber As
Integer, _
ByVal dwCallbackReason As Integer, ByVal hSourceFile As Integer, _
ByVal hDestinationFile As Integer, ByRef lpData As Integer) As
Integer

Select Case dwCallbackReason
Case CALLBACK_STREAM_SWITCH

'this value is passed whenever the
'callback is initialized for each file.
'F_Migration.DefInstance.ProgressBar1.Value = 0
'F_Migration.DefInstance.ProgressBar1.Min = 0
'F_Migration.DefInstance.ProgressBar1.Max = (TotalFileSize *
10000)
'F_Migration.DefInstance.ProgressBar1.CtlRefresh()

CopyProgressCallback = PROGRESS_CONTINUE

Case CALLBACK_CHUNK_FINISHED

'called when a block has been copied
'F_Migration.DefInstance.ProgressBar1.Value =
(TotalBytesTransferred * 10000)

'optional. While the app is copying it
'will not respond to input for canceling.
System.Windows.Forms.Application.DoEvents()

CopyProgressCallback = PROGRESS_CONTINUE

End Select
CopyProgressCallback = PROGRESS_CONTINUE

End Function
End Module

vb.net

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Dim lpCallback As CPCallback
Dim bUseCallback As Boolean
Dim fcSuccess As Integer
Dim sSourcefile, sTargetFile As String
Dim bcancelbackup As Boolean
bcancelbackup = False
bUseCallback = True

sSourcefile = "c:\document.xml"
sTargetFile = "c:\temp\document.xml"
'
If bUseCallback Then

fcSuccess = CopyFileEx(sSourcefile, sTargetFile, AddressOf
CopyProgressCallback, _
0, bcancelbackup, COPY_FILE_RESTARTABLE) = 1
End If
End Sub

Option Strict Off
Option Explicit On
Module Module1

Public Const MAXDWORD As Integer = &HFFFFFFFF
Public Const MAX_PATH As Integer = 260
Public Const INVALID_HANDLE_VALUE As Integer = -1
Public Const FILE_ATTRIBUTE_DIRECTORY As Integer = &H10S

'Define possible return codes from the CopyFileEx callback routine
Public Const PROGRESS_CONTINUE As Integer = 0
Public Const PROGRESS_CANCEL As Integer = 1
Public Const PROGRESS_STOP As Integer = 2
Public Const PROGRESS_QUIET As Integer = 3

'CopyFileEx callback routine state change values
Public Const CALLBACK_CHUNK_FINISHED As Integer = &H0S
Public Const CALLBACK_STREAM_SWITCH As Integer = &H1S

'CopyFileEx option flags
Public Const COPY_FILE_FAIL_IF_EXISTS As Integer = &H1S
Public Const COPY_FILE_RESTARTABLE As Integer = &H2S
Public Const COPY_FILE_OPEN_SOURCE_FOR_WRITE As Integer = &H4S

Public Declare Function CopyFileEx Lib "kernel32" Alias "CopyFileExA" _
(ByVal lpExistingFileName As String, ByVal lpNewFileName As String, _
ByVal lpProgressRoutine As CPCallback, ByVal lpData As Long, ByVal
pbCancel As Integer, _
ByVal dwCopyFlags As Integer) As Integer

Public Delegate Function CPCallback(ByVal TotalFileSize As Decimal, _
ByVal TotalBytesTransferred As Decimal, ByVal StreamSize As
Decimal, _
ByVal StreamBytesTransferred As Decimal, ByVal dwStreamNumber As
Integer, _
ByVal dwCallbackReason As Integer, ByVal hSourceFile As Integer, _
ByVal hDestinationFile As Integer, ByRef lpData As Integer) As
Integer

Public Function CopyProgressCallback(ByVal TotalFileSize As Decimal, _
ByVal TotalBytesTransferred As Decimal, ByVal StreamSize As
Decimal, _
ByVal StreamBytesTransferred As Decimal, ByVal dwStreamNumber As
Integer, _
ByVal dwCallbackReason As Integer, ByVal hSourceFile As Integer, _
ByVal hDestinationFile As Integer, ByRef lpData As Integer) As
Integer

Select Case dwCallbackReason
Case CALLBACK_STREAM_SWITCH

'this value is passed whenever the
'callback is initialized for each file.

'F_Migration.DefInstance.ProgressBar1.Value = 0
'F_Migration.DefInstance.ProgressBar1.Min = 0
'F_Migration.DefInstance.ProgressBar1.Max = (TotalFileSize *
10000)
'F_Migration.DefInstance.ProgressBar1.CtlRefresh()

CopyProgressCallback = PROGRESS_CONTINUE

Case CALLBACK_CHUNK_FINISHED

'called when a block has been copied
'F_Migration.DefInstance.ProgressBar1.Value =
(TotalBytesTransferred * 10000)

'optional. While the app is copying it
'will not respond to input for canceling.
System.Windows.Forms.Application.DoEvents()

CopyProgressCallback = PROGRESS_CONTINUE

End Select
CopyProgressCallback = PROGRESS_CONTINUE

End Function
End Module

Thanks

Paul
 
Hi,


Public Declare Auto Function CopyFileEx Lib "kernel32" _
(ByVal lpExistingFileName As String, ByVal lpNewFileName As String, _
ByVal lpProgressRoutine As CPCallback, ByVal lpData As Long, ByVal
pbCancel As Boolean, ByVal dwCopyFlags As Integer) As Integer

Public Declare Auto Function CopyFileEx Lib "kernel32" ( _
ByVal lpExistingFileName As String, _
ByVal lpNewFileName As String, _
ByVal lpProgressRoutine As CPCallback, _
ByRef lpData As Long, _
ByRef pbCancel As Boolean, _
ByVal dwCopyFlags As Integer) As Integer


This way CopyFileEx will work, but changing pbCancel during copy will not
have an effect. If you need it to work, then there are workarounds, but I
guess you don't need it because you can always cancel it from within
ProgressRoutine using the return value.
Public Delegate Function CPCallback(ByVal TotalFileSize As Decimal, _
ByVal TotalBytesTransferred As Decimal, ByVal StreamSize As
Decimal, _
ByVal StreamBytesTransferred As Decimal, ByVal dwStreamNumber As
Integer, _
ByVal dwCallbackReason As Integer, ByVal hSourceFile As Integer, _
ByVal hDestinationFile As Integer, ByRef lpData As Integer) As
Integer

VB6 has no 64bit integer, so Currency * 10000 was a hack.
VB.NET has a 64bit integer data type : Long.

Public Delegate Function CPCallback( _
ByVal TotalFileSize As Long, _
ByVal TotalBytesTransfered As Long, _
ByVal StreamSize As Long, _
ByVal StreamBytesTransfered As Long, _
ByVal StreamNumber As Integer, _
ByVal dwCallbackReason As Integer, _
ByVal hSourceFile As IntPtr, _
ByVal hDestFile As IntPtr, _
ByRef lpData As Long ) As Integer


HTH,
greetings

Public Function CopyProgressCallback(ByVal TotalFileSize As Decimal, _
ByVal TotalBytesTransferred As Decimal, ByVal StreamSize As
Decimal, _
ByVal StreamBytesTransferred As Decimal, ByVal dwStreamNumber As
Integer, _
ByVal dwCallbackReason As Integer, ByVal hSourceFile As Integer, _
ByVal hDestinationFile As Integer, ByRef lpData As Integer) As
Integer

Select Case dwCallbackReason
Case CALLBACK_STREAM_SWITCH

'this value is passed whenever the
'callback is initialized for each file.
'F_Migration.DefInstance.ProgressBar1.Value = 0
'F_Migration.DefInstance.ProgressBar1.Min = 0
'F_Migration.DefInstance.ProgressBar1.Max = (TotalFileSize *
10000)
'F_Migration.DefInstance.ProgressBar1.CtlRefresh()

CopyProgressCallback = PROGRESS_CONTINUE

Case CALLBACK_CHUNK_FINISHED

'called when a block has been copied
'F_Migration.DefInstance.ProgressBar1.Value =
(TotalBytesTransferred * 10000)

'optional. While the app is copying it
'will not respond to input for canceling.
System.Windows.Forms.Application.DoEvents()

CopyProgressCallback = PROGRESS_CONTINUE

End Select
CopyProgressCallback = PROGRESS_CONTINUE

End Function
End Module

vb.net

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Dim lpCallback As CPCallback
Dim bUseCallback As Boolean
Dim fcSuccess As Integer
Dim sSourcefile, sTargetFile As String
Dim bcancelbackup As Boolean
bcancelbackup = False
bUseCallback = True

sSourcefile = "c:\document.xml"
sTargetFile = "c:\temp\document.xml"
'
If bUseCallback Then

fcSuccess = CopyFileEx(sSourcefile, sTargetFile, AddressOf
CopyProgressCallback, _
0, bcancelbackup, COPY_FILE_RESTARTABLE) = 1
End If
End Sub

Option Strict Off
Option Explicit On
Module Module1

Public Const MAXDWORD As Integer = &HFFFFFFFF
Public Const MAX_PATH As Integer = 260
Public Const INVALID_HANDLE_VALUE As Integer = -1
Public Const FILE_ATTRIBUTE_DIRECTORY As Integer = &H10S

'Define possible return codes from the CopyFileEx callback routine
Public Const PROGRESS_CONTINUE As Integer = 0
Public Const PROGRESS_CANCEL As Integer = 1
Public Const PROGRESS_STOP As Integer = 2
Public Const PROGRESS_QUIET As Integer = 3

'CopyFileEx callback routine state change values
Public Const CALLBACK_CHUNK_FINISHED As Integer = &H0S
Public Const CALLBACK_STREAM_SWITCH As Integer = &H1S

'CopyFileEx option flags
Public Const COPY_FILE_FAIL_IF_EXISTS As Integer = &H1S
Public Const COPY_FILE_RESTARTABLE As Integer = &H2S
Public Const COPY_FILE_OPEN_SOURCE_FOR_WRITE As Integer = &H4S

Public Declare Function CopyFileEx Lib "kernel32" Alias "CopyFileExA" _
(ByVal lpExistingFileName As String, ByVal lpNewFileName As String, _
ByVal lpProgressRoutine As CPCallback, ByVal lpData As Long, ByVal
pbCancel As Integer, _
ByVal dwCopyFlags As Integer) As Integer

Public Delegate Function CPCallback(ByVal TotalFileSize As Decimal, _
ByVal TotalBytesTransferred As Decimal, ByVal StreamSize As
Decimal, _
ByVal StreamBytesTransferred As Decimal, ByVal dwStreamNumber As
Integer, _
ByVal dwCallbackReason As Integer, ByVal hSourceFile As Integer, _
ByVal hDestinationFile As Integer, ByRef lpData As Integer) As
Integer

Public Function CopyProgressCallback(ByVal TotalFileSize As Decimal, _
ByVal TotalBytesTransferred As Decimal, ByVal StreamSize As
Decimal, _
ByVal StreamBytesTransferred As Decimal, ByVal dwStreamNumber As
Integer, _
ByVal dwCallbackReason As Integer, ByVal hSourceFile As Integer, _
ByVal hDestinationFile As Integer, ByRef lpData As Integer) As
Integer

Select Case dwCallbackReason
Case CALLBACK_STREAM_SWITCH

'this value is passed whenever the
'callback is initialized for each file.

'F_Migration.DefInstance.ProgressBar1.Value = 0
'F_Migration.DefInstance.ProgressBar1.Min = 0
'F_Migration.DefInstance.ProgressBar1.Max = (TotalFileSize *
10000)
'F_Migration.DefInstance.ProgressBar1.CtlRefresh()

CopyProgressCallback = PROGRESS_CONTINUE

Case CALLBACK_CHUNK_FINISHED

'called when a block has been copied
'F_Migration.DefInstance.ProgressBar1.Value =
(TotalBytesTransferred * 10000)

'optional. While the app is copying it
'will not respond to input for canceling.
System.Windows.Forms.Application.DoEvents()

CopyProgressCallback = PROGRESS_CONTINUE

End Select
CopyProgressCallback = PROGRESS_CONTINUE

End Function
End Module

Thanks

Paul


 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Back
Top