123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207 |
- using Microsoft.WindowsAPICodePack.Taskbar;
- using System;
- using System.IO;
- using System.Threading;
- using System.Windows.Forms;
- namespace StrangeFileCopy
- {
- public partial class MainForm : Form
- {
- private string _status = "Ready";
- private int _bufProgress;
- private int _reOpenProgress;
- private int _totalProgress;
- private bool _pause;
- private bool _error;
- public MainForm() => InitializeComponent();
- private void FireButton_Click(object sender, EventArgs e)
- {
- var srcPath = FromTextBox.Text;
- var dstPath = ToTextBox.Text;
- if (string.IsNullOrWhiteSpace(srcPath) || string.IsNullOrWhiteSpace(dstPath))
- {
- MessageBox.Show("Before start,fill `File From' and `To Folder'");
- return;
- }
- var blkSize = MaxCheckBox.Checked ? 2147483591 : (int)BufSizeUpDown.Value * 1024 * 1024;
- var reOpenTimes = (int)Math.Ceiling(ReOpenSizeUnDown.Value * 1024 * 1024 * 1024 / blkSize);
- var flush = FlushCheckBox.Checked;
- FireButton.Enabled = false;
- ConfigGroupBox.Enabled = false;
- new Thread(() =>
- {
- FileStream src = null;
- FileStream dst = null;
- try
- {
- _status = "Opening Source";
- src = File.OpenRead(srcPath);
- var srcLen = src.Length;
- _status = "Pre allocating Dest - Opening";
- dst = File.OpenWrite(dstPath);
- _status = "Pre allocating Dest - Seeking";
- dst.Position = src.Length - 1;
- _status = "Pre allocating Dest - Writing";
- dst.WriteByte(0);
- _status = "Pre allocating Dest - Flushing";
- dst.Flush(true);
- _status = "Pre allocating Dest - Closing";
- dst.Close();
- long pos = 0;
- var buf = new byte[blkSize];
- while (pos < srcLen)
- {
- _status = "Opening Dest";
- dst = File.OpenWrite(dstPath);
- dst.Position = pos;
- for (var i = 0; i < reOpenTimes; i++)
- {
- _status = "Reading Source";
- var bi = 0;
- var read = 0;
- do
- {
- read = src.Read(buf, bi, blkSize - read);
- bi += read;
- _bufProgress = (int)(100 * (float)bi / blkSize);
- } while (read > 0 && bi < blkSize);
- _status = "Writing Dst";
- dst.Write(buf, 0, bi);
- _status = "Flushing Dst";
- if (flush) dst.Flush(true);
- _reOpenProgress = (int)(100 * (float)i / reOpenTimes);
- _totalProgress = (int)(100 * (float)src.Position / srcLen);
- if (_pause)
- {
- _status = "Paused";
- while (_pause)
- {
- Thread.Sleep(250);
- }
- }
- if (src.Position == srcLen) break;
- }
- pos = src.Position;
- _status = "Closing Dst";
- dst.Close();
- }
- _status = "Done";
- }
- catch (Exception exception)
- {
- _status = $"Error:{exception.Message}";
- _error = true;
- }
- finally
- {
- src?.Close();
- try
- {
- dst?.Close();
- }
- catch
- {
- //ignore
- }
- }
- }).Start();
- }
- private void UiUpdateTimer_Tick(object sender, EventArgs e)
- {
- CurrentOperationLabel.Text = _status;
- BufProgressBar.Value = _bufProgress;
- ReOpenProgressBar.Value = _reOpenProgress;
- TotalProgressBar.Value = _totalProgress;
- if (_error)
- {
- TaskbarManager.Instance.SetProgressState(TaskbarProgressBarState.Error);
- }
- else
- {
- TaskbarManager.Instance.SetProgressState(_pause ? TaskbarProgressBarState.Paused : TaskbarProgressBarState.Normal);
- TaskbarManager.Instance.SetProgressValue(_totalProgress, 100);
- }
- }
- private void FromTextBox_DragEnter(object sender, DragEventArgs e)
- {
- string[] files;
- e.Effect = e.Data.GetDataPresent(DataFormats.FileDrop)
- && (files = (string[])e.Data.GetData(DataFormats.FileDrop)).Length == 1
- && File.Exists(files[0])
- ? DragDropEffects.Copy
- : DragDropEffects.None;
- }
- private void FromTextBox_DragDrop(object sender, DragEventArgs e) => FromTextBox.Text = ((string[])e.Data.GetData(DataFormats.FileDrop))[0];
- private void ToTextBox_DragEnter(object sender, DragEventArgs e)
- {
- string[] files;
- e.Effect = e.Data.GetDataPresent(DataFormats.FileDrop)
- && (files = (string[])e.Data.GetData(DataFormats.FileDrop)).Length == 1
- && Directory.Exists(files[0])
- ? DragDropEffects.Copy
- : DragDropEffects.None;
- }
- private void ToTextBox_DragDrop(object sender, DragEventArgs e)
- {
- var to = ((string[])e.Data.GetData(DataFormats.FileDrop))[0];
- new Thread(() =>
- {
- Invoke(new Action(delegate
- {
- if (string.IsNullOrWhiteSpace(FromTextBox.Text))
- {
- MessageBox.Show("Fill `File from' first!");
- return;
- }
- var filename = Path.GetFileName(FromTextBox.Text);
- var dest = Path.Combine(to, filename);
- if (File.Exists(dest))
- {
- if (DialogResult.Yes == MessageBox.Show("Target file exist,override it?", "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2))
- {
- ToTextBox.Text = dest;
- }
- else
- {
- ToTextBox.Clear();
- }
- }
- else
- {
- ToTextBox.Text = dest;
- }
- }));
- }).Start();
- }
- private void MaxCheckBox_CheckedChanged(object sender, EventArgs e) => BufSizeUpDown.Enabled = !MaxCheckBox.Checked;
- private void PauseCheckBox_CheckedChanged(object sender, EventArgs e) => _pause = PauseCheckBox.Checked;
- }
- }
|