Created
December 13, 2016 11:57
-
-
Save tugberkugurlu/61a2055b4907c8f9103804a5454b9144 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.ComponentModel; | |
using System.IO; | |
using System.Linq; | |
using System.Runtime.InteropServices; | |
using System.Text; | |
using System.Threading.Tasks; | |
namespace ConsoleApp6 | |
{ | |
// see: https://msdn.microsoft.com/en-us/library/windows/desktop/aa363852(v=vs.85).aspx | |
class Program | |
{ | |
private static string destinationFilePath = @"D:\images\copies\ubuntu-14.04.2-desktop-amd64.iso"; | |
static void Main(string[] args) | |
{ | |
int IsCancelled = 0; | |
var source = @"D:\images\ubuntu-14.04.2-desktop-amd64.iso"; | |
bool result = CopyFileEx(source, destinationFilePath, new CopyProgressRoutine(CopyProgressHandler), IntPtr.Zero, ref IsCancelled, CopyFileFlags.COPY_FILE_OPEN_SOURCE_FOR_WRITE | CopyFileFlags.COPY_FILE_ALLOW_DECRYPTED_DESTINATION); | |
if (!result) | |
{ | |
//when ever we get the result as false it means some error occured so get the last win 32 error. | |
throw new Win32Exception(Marshal.GetLastWin32Error()); | |
} | |
} | |
private static void OnProgressChanged(double percentage) | |
{ | |
Console.WriteLine($"Percentage: {percentage}"); | |
} | |
private static void OnCompleted() | |
{ | |
Console.WriteLine("Completed!"); | |
} | |
private static CopyProgressResult CopyProgressHandler(long total, long transferred, long streamSize, long streamByteTrans, uint dwStreamNumber, | |
CopyProgressCallbackReason reason, IntPtr hSourceFile, IntPtr hDestinationFile, IntPtr lpData) | |
{ | |
//when a chunk is finished call the progress changed. | |
if (reason == CopyProgressCallbackReason.CALLBACK_CHUNK_FINISHED) | |
{ | |
OnProgressChanged((transferred / (double)total) * 100.0); | |
} | |
//transfer completed | |
if (transferred >= total) | |
{ | |
//if file is read only, remove read-only attribute(case to handle CD drive import) | |
FileAttributes attr = File.GetAttributes(destinationFilePath); | |
if ((attr & FileAttributes.ReadOnly) == FileAttributes.ReadOnly) | |
{ | |
attr = attr & ~FileAttributes.ReadOnly; | |
File.SetAttributes(destinationFilePath, attr); | |
} | |
OnCompleted(); | |
} | |
return CopyProgressResult.PROGRESS_CONTINUE; | |
} | |
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] | |
[return: MarshalAs(UnmanagedType.Bool)] | |
private static extern bool CopyFileEx(string lpExistingFileName, string lpNewFileName, CopyProgressRoutine lpProgressRoutine, IntPtr lpData, ref Int32 pbCancel, CopyFileFlags dwCopyFlags); | |
private delegate CopyProgressResult CopyProgressRoutine(long TotalFileSize, long TotalBytesTransferred, long StreamSize, long StreamBytesTransferred, uint dwStreamNumber, CopyProgressCallbackReason dwCallbackReason, | |
IntPtr hSourceFile, IntPtr hDestinationFile, IntPtr lpData); | |
private enum CopyProgressResult : uint | |
{ | |
PROGRESS_CONTINUE = 0, | |
PROGRESS_CANCEL = 1, | |
PROGRESS_STOP = 2, | |
PROGRESS_QUIET = 3 | |
} | |
private enum CopyProgressCallbackReason : uint | |
{ | |
CALLBACK_CHUNK_FINISHED = 0x00000000, | |
CALLBACK_STREAM_SWITCH = 0x00000001 | |
} | |
[Flags] | |
private enum CopyFileFlags : uint | |
{ | |
COPY_FILE_FAIL_IF_EXISTS = 0x00000001, | |
COPY_FILE_NO_BUFFERING = 0x00001000, | |
COPY_FILE_RESTARTABLE = 0x00000002, | |
COPY_FILE_OPEN_SOURCE_FOR_WRITE = 0x00000004, | |
COPY_FILE_ALLOW_DECRYPTED_DESTINATION = 0x00000008 | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment