RDPAddins.NET/FileTransfer/FileTransferAddin/FileTransferAddin.cs

268 lines
9.7 KiB
C#

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<string, int> icons = new Dictionary<string, int>();
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();
}
}
}