using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Linq; using System.Text; using System.Windows.Forms; using RDPAddins.Common; using System.IO; using System.IO.Compression; using System.Threading.Tasks; using System.ComponentModel.Composition; using System.Diagnostics; using System.Threading; namespace FileTransfer { [AddinMetadata("File transfer", "FTFTA1", ChannelOptions.Compress | ChannelOptions.PriorityLow)] public partial class FileTransferAddin : UserControl, IAddin { public void Initialize(IChannel Channel) { this.Channel = Channel; Channel.Connected += new EventHandler(FileTransferAddin_Connected); Channel.Disconnected += new EventHandler(Channel_Disconnected); Channel.UI.BalloonTipClicked += new BalloonTipClickedHandler((ui, context) => StartFile((string)context)); Channel.UI.MenuCreating += new MenuCreatingHandler(ui => mnuHolder); Channel.UI.IconCreating += new IconCreatingHandler(ui => Properties.Resources.AddinIcon); Channel.UI.ControlCreating += new ControlCreatingHandler(ui => this); } void Channel_Disconnected(object sender, EventArgs e) { if (stopWaiting != null) { stopWaiting.Cancel(); stopWaiting = null; } } protected FileTransferAddin() { InitializeComponent(); } IChannel Channel; CancellationTokenSource stopWaiting; void FileTransferAddin_Connected(object sender, EventArgs e) { stopWaiting = new CancellationTokenSource(); Task.Factory.StartNew(token => { while (true) { try { string file = WaitForFile((CancellationToken)token); NewFile(file); } catch (OperationCanceledException) { break; } catch { } } }, stopWaiting.Token, stopWaiting.Token); } private void lvMain_MouseDoubleClick(object sender, MouseEventArgs e) { if (lvMain.SelectedItems.Count > 0) { StartFile(lvMain.SelectedItems[0].SubItems[1].Text); } } void StartFile(string filename) { if (!string.IsNullOrWhiteSpace(filename)) Task.Factory.StartNew(() => { try { System.Diagnostics.Process.Start(filename); } catch { } }); } private void mnuLVCSaveAs_Click(object sender, EventArgs e) { if (lvMain.SelectedItems.Count > 0) { string fileSavePath = string.Empty; if (saveFileDialog.ShowDialog() == DialogResult.OK) { fileSavePath = saveFileDialog.FileName; try { System.IO.File.Copy(lvMain.SelectedItems[0].SubItems[1].Text, fileSavePath, true); } catch (Exception ex) { MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } } } private void mnuLVCOpen_Click(object sender, EventArgs e) { lvMain_MouseDoubleClick(null, null); } Dictionary icons = new Dictionary(); int GetIconIndex(string filename, bool upload) { string ext = (upload ? "u" : "d") + Path.GetExtension(filename); int iconindex = 0; if (icons.ContainsKey(ext)) iconindex = icons[ext]; else { using (var icon = System.Drawing.Icon.ExtractAssociatedIcon(filename)) { var bmp = icon.ToBitmap(); using (var gr = Graphics.FromImage(bmp)) { using (var img = upload ? Properties.Resources.Uploaded : Properties.Resources.Downloaded) { gr.DrawImage(img, 0, 19, 12, 12); } } ilMain.Images.Add(bmp); iconindex = ilMain.Images.Count - 1; if (!ext.Contains("exe")) icons[ext] = iconindex; } } return iconindex; } public void NewFile(string filename) { Channel.UI.DoOnUIThread(() => lvMain.Items.Add(new ListViewItem(new string[] { DateTime.Now.ToString(), filename }, GetIconIndex(filename, false)))); System.Media.SystemSounds.Exclamation.Play(); if (Properties.Settings.Default.AutoOpen) StartFile(filename); else Channel.UI.ShowBalloonTip(2000, Channel.Metadata.AddinName, filename, ToolTipIcon.Info, filename); } public string WaitForFile(CancellationToken token) { byte[] buffer = new byte[0x1000]; int toreadhead = 12; int readedonce = 0; int readed = 0; while (toreadhead > 0) { readedonce = Channel.Read(buffer, readed, toreadhead); { if (readedonce > 0) { readed += readedonce; toreadhead -= readedonce; } } token.ThrowIfCancellationRequested(); Thread.Sleep(100); } long toread = BitConverter.ToInt64(buffer, 0); int toreadname = BitConverter.ToInt32(buffer, 8); readed = 0; while (toreadname > 0) { readedonce = Channel.Read(buffer, readed, toreadname); if (readedonce > 0) { readed += readedonce; toreadname -= readedonce; } token.ThrowIfCancellationRequested(); } long maxread = toread; Channel.UI.DoOnUIThread(() => { pbMain.Value = 0; pbMain.Visible = true; }); string filename = Path.Combine(Path.GetTempPath(), System.Text.Encoding.UTF8.GetString(buffer, 0, readed)); using (FileStream fs = File.OpenWrite(filename)) { while (toread > 0) { readedonce = Channel.Read(buffer, 0, buffer.Length); if (readedonce > 0) { fs.Write(buffer, 0, readedonce); toread -= readedonce; Channel.UI.DoOnUIThread(()=> pbMain.Value = (int)(pbMain.Maximum * (maxread - toread) / (double)maxread)); } token.ThrowIfCancellationRequested(); } } Channel.UI.DoOnUIThread(() => pbMain.Visible = false); return filename; } private void mnuHSend_Click(object sender, EventArgs e) { btSend.Visible = false; mnuHSend.Enabled = false; string fileOpenPath = string.Empty; if (openFileDialog.ShowDialog() == DialogResult.OK) { fileOpenPath = openFileDialog.FileName; byte[] filename = System.Text.Encoding.UTF8.GetBytes(Path.GetFileName(fileOpenPath)); Task.Factory.StartNew(() => { byte[] buffer = new byte[1600]; int bytesRead = 0; using (FileStream fs = File.OpenRead(fileOpenPath)) { long readed = 0, maxread = fs.Length; Channel.Write(BitConverter.GetBytes(maxread), 0, 8); Channel.Write(BitConverter.GetBytes(filename.Length), 0, 4); Channel.Write(filename, 0, filename.Length); Channel.UI.DoOnUIThread(() => { pbMain.Value = 0; pbMain.Visible = true; }); while ((bytesRead = fs.Read(buffer, 0, buffer.Length)) != 0) { Channel.Write(buffer, 0, bytesRead); readed += bytesRead; Channel.UI.DoOnUIThread(() => pbMain.Value = (int)(pbMain.Maximum * readed / (double)maxread)); } Channel.UI.DoOnUIThread(() => pbMain.Visible = false); } Channel.UI.DoOnUIThread(() => { lvMain.Items.Add(new ListViewItem(new string[] { DateTime.Now.ToString(), fileOpenPath }, GetIconIndex(fileOpenPath, true))); btSend.Visible = true; mnuHSend.Enabled = true; }); }); } else { btSend.Visible = true; mnuHSend.Enabled = true; } } private void mnuHAuto_Click(object sender, EventArgs e) { var menu = (MenuItem)sender; menu.Checked = !menu.Checked; Properties.Settings.Default.AutoOpen = mnuHAuto.Checked; Properties.Settings.Default.Save(); } } }