From 62d9ddd03ebd71bd778deb3b83c3d73665b42472 Mon Sep 17 00:00:00 2001 From: huiyadanli Date: Mon, 5 Mar 2018 22:58:28 +0800 Subject: [PATCH] [#] Clean up code and catch exceptions to prompt --- .../Core/{ClipData.cs => ClipboardData.cs} | 4 +- PasteEx/Core/Processor/BaseProcessor.cs | 4 +- PasteEx/Core/Processor/FileProcessor.cs | 2 +- PasteEx/Core/Processor/HtmlProcessor.cs | 2 +- PasteEx/Core/Processor/ImageProcessor.cs | 21 +++-- PasteEx/Core/Processor/RtfProcessor.cs | 2 +- PasteEx/Core/Processor/TextProcessor.cs | 2 +- PasteEx/FormMain.cs | 19 +++-- PasteEx/Library/Kernel32.cs | 18 +++++ PasteEx/PasteEx.csproj | 2 + PasteEx/Program.cs | 4 +- PasteEx/Resources/Resource-en-US.Designer.cs | 78 ++++++++++++++++++- PasteEx/Resources/Resource-en-US.resx | 28 ++++++- PasteEx/Resources/Resource-zh-CN.Designer.cs | 60 +++++++++++++- PasteEx/Resources/Resource-zh-CN.resx | 24 +++++- PasteEx/RightMenu.cs | 8 +- PasteEx/Util/CommandLine.cs | 36 +++++++++ 17 files changed, 275 insertions(+), 39 deletions(-) rename PasteEx/Core/{ClipData.cs => ClipboardData.cs} (97%) create mode 100644 PasteEx/Library/Kernel32.cs create mode 100644 PasteEx/Util/CommandLine.cs diff --git a/PasteEx/Core/ClipData.cs b/PasteEx/Core/ClipboardData.cs similarity index 97% rename from PasteEx/Core/ClipData.cs rename to PasteEx/Core/ClipboardData.cs index 70c89a9..f17c027 100644 --- a/PasteEx/Core/ClipData.cs +++ b/PasteEx/Core/ClipboardData.cs @@ -5,7 +5,7 @@ namespace PasteEx.Core { - public class ClipData + public class ClipboardData { public IDataObject IAcquisition { get; set; } @@ -21,7 +21,7 @@ protected virtual void OnSaveCompleted() SaveCompleted?.Invoke(); } - public ClipData(IDataObject iDataObject) + public ClipboardData(IDataObject iDataObject) { IAcquisition = iDataObject; Storage = new DataObject(); diff --git a/PasteEx/Core/Processor/BaseProcessor.cs b/PasteEx/Core/Processor/BaseProcessor.cs index 3b9590f..36d1b46 100644 --- a/PasteEx/Core/Processor/BaseProcessor.cs +++ b/PasteEx/Core/Processor/BaseProcessor.cs @@ -6,9 +6,9 @@ namespace PasteEx.Core public abstract class BaseProcessor { - public ClipData Data { get; set; } + public ClipboardData Data { get; set; } - public BaseProcessor(ClipData clipData) + public BaseProcessor(ClipboardData clipData) { Data = clipData; } diff --git a/PasteEx/Core/Processor/FileProcessor.cs b/PasteEx/Core/Processor/FileProcessor.cs index 3c468a0..aad055a 100644 --- a/PasteEx/Core/Processor/FileProcessor.cs +++ b/PasteEx/Core/Processor/FileProcessor.cs @@ -8,7 +8,7 @@ namespace PasteEx.Core { public class FileProcessor : BaseProcessor { - public FileProcessor(ClipData clipData) : base(clipData) + public FileProcessor(ClipboardData clipData) : base(clipData) { Data = clipData; } diff --git a/PasteEx/Core/Processor/HtmlProcessor.cs b/PasteEx/Core/Processor/HtmlProcessor.cs index ff28481..948699b 100644 --- a/PasteEx/Core/Processor/HtmlProcessor.cs +++ b/PasteEx/Core/Processor/HtmlProcessor.cs @@ -7,7 +7,7 @@ namespace PasteEx.Core { public class HtmlProcessor : BaseProcessor { - public HtmlProcessor(ClipData clipData) : base(clipData) + public HtmlProcessor(ClipboardData clipData) : base(clipData) { Data = clipData; } diff --git a/PasteEx/Core/Processor/ImageProcessor.cs b/PasteEx/Core/Processor/ImageProcessor.cs index 9236698..324e4dd 100644 --- a/PasteEx/Core/Processor/ImageProcessor.cs +++ b/PasteEx/Core/Processor/ImageProcessor.cs @@ -19,7 +19,7 @@ public class ImageProcessor : BaseProcessor private string analyzeExt; - public ImageProcessor(ClipData clipData) : base(clipData) + public ImageProcessor(ClipboardData clipData) : base(clipData) { Data = clipData; } @@ -209,21 +209,32 @@ private Bitmap GetImageFromDataObjectOld(DataObject retrievedData) return bitmap; } - private void GetImageFromUrl(string url, string path) + private async void GetImageFromUrl(string url, string path) { WebClient client = new WebClient(); client.DownloadFileCompleted += (sender, e) => { - OnSaveAsFileCompleted(); + //... }; client.DownloadProgressChanged += (sender, e) => { //this.proBarDownLoad.Minimum = 0; //this.proBarDownLoad.Maximum = (int)e.TotalBytesToReceive; //this.proBarDownLoad.Value = (int)e.BytesReceived; - FormMain.GetInstance().ChangeTsslCurrentLocation($"下载图片中...{e.ProgressPercentage}%"); + FormMain.GetInstance().ChangeTsslCurrentLocation( + String.Format(Resources.Resource_zh_CN.TipPictureDownloading, e.ProgressPercentage)); }; - client.DownloadFileTaskAsync(new Uri(url), path); + try + { + await client.DownloadFileTaskAsync(new Uri(url), path); + } + catch (Exception ex) + { + Logger.Error(ex); + MessageBox.Show(Resources.Resource_zh_CN.TipDownloadFailed + " : " + ex.Message, + Resources.Resource_zh_CN.TitleError, MessageBoxButtons.OK, MessageBoxIcon.Error); + } + OnSaveAsFileCompleted(); } } } diff --git a/PasteEx/Core/Processor/RtfProcessor.cs b/PasteEx/Core/Processor/RtfProcessor.cs index 01fd2ac..520b139 100644 --- a/PasteEx/Core/Processor/RtfProcessor.cs +++ b/PasteEx/Core/Processor/RtfProcessor.cs @@ -7,7 +7,7 @@ namespace PasteEx.Core { public class RtfProcessor : BaseProcessor { - public RtfProcessor(ClipData clipData) : base(clipData) + public RtfProcessor(ClipboardData clipData) : base(clipData) { Data = clipData; } diff --git a/PasteEx/Core/Processor/TextProcessor.cs b/PasteEx/Core/Processor/TextProcessor.cs index 0c4cac4..b2beb08 100644 --- a/PasteEx/Core/Processor/TextProcessor.cs +++ b/PasteEx/Core/Processor/TextProcessor.cs @@ -10,7 +10,7 @@ namespace PasteEx.Core { public class TextProcessor : BaseProcessor { - public TextProcessor(ClipData clipData) : base(clipData) + public TextProcessor(ClipboardData clipData) : base(clipData) { Data = clipData; } diff --git a/PasteEx/FormMain.cs b/PasteEx/FormMain.cs index 7ccb67f..ea63a36 100644 --- a/PasteEx/FormMain.cs +++ b/PasteEx/FormMain.cs @@ -1,10 +1,7 @@ using PasteEx.Core; using System; -using System.ComponentModel; using System.IO; -using System.Net; using System.Text; -using System.Threading.Tasks; using System.Windows.Forms; namespace PasteEx @@ -13,7 +10,7 @@ public partial class FormMain : Form { private static FormMain dialogue = null; - private ClipData data; + private ClipboardData data; private string currentLocation; @@ -54,7 +51,7 @@ public FormMain(string location) private void FormMain_Load(object sender, EventArgs e) { - data = new ClipData(Clipboard.GetDataObject()); + data = new ClipboardData(Clipboard.GetDataObject()); data.SaveCompleted += () => Application.Exit(); // exit when save completed string[] extensions = data.Analyze(); cboExtension.Items.AddRange(extensions); @@ -214,7 +211,7 @@ private void btnSave_Click(object sender, EventArgs e) if (File.Exists(path)) { - DialogResult result = MessageBox.Show(String.Format("目标文件{0}已经存在,是否覆盖?", path), + DialogResult result = MessageBox.Show(String.Format(Resources.Resource_zh_CN.TipTargetFileExisted, path), Resources.Resource_zh_CN.Title, MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (result == DialogResult.Yes) { @@ -279,7 +276,7 @@ protected override bool ProcessCmdKey(ref Message msg, Keys keyData) public static void QuickPasteEx(string location) { - ClipData data = new ClipData(Clipboard.GetDataObject()); + ClipboardData data = new ClipboardData(Clipboard.GetDataObject()); string[] extensions = data.Analyze(); if (extensions.Length > 0) @@ -293,14 +290,15 @@ public static void QuickPasteEx(string location) string path = location + GenerateFileName(currentLocation, extensions[0]) + "." + extensions[0]; if (!Directory.Exists(currentLocation)) { - MessageBox.Show("粘贴目标路径不存在", + Console.WriteLine(Resources.Resource_zh_CN.TipTargetPathNotExist); + MessageBox.Show(Resources.Resource_zh_CN.TipTargetPathNotExist, Resources.Resource_zh_CN.Title, MessageBoxButtons.OK, MessageBoxIcon.Warning); } else { if (File.Exists(path)) { - DialogResult result = MessageBox.Show(String.Format("目标文件{0}已经存在,是否覆盖?", path), + DialogResult result = MessageBox.Show(String.Format(Resources.Resource_zh_CN.TipTargetFileExisted, path), Resources.Resource_zh_CN.Title, MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question); if (result == DialogResult.Yes) { @@ -319,7 +317,8 @@ public static void QuickPasteEx(string location) } else { - MessageBox.Show("剪贴板内容为空或不被支持", + Console.WriteLine(Resources.Resource_zh_CN.TipAnalyzeFailedWithoutPrompt); + MessageBox.Show(Resources.Resource_zh_CN.TipAnalyzeFailedWithoutPrompt, Resources.Resource_zh_CN.Title, MessageBoxButtons.OK, MessageBoxIcon.Warning); } } diff --git a/PasteEx/Library/Kernel32.cs b/PasteEx/Library/Kernel32.cs new file mode 100644 index 0000000..8629ffd --- /dev/null +++ b/PasteEx/Library/Kernel32.cs @@ -0,0 +1,18 @@ +using System; +using System.Runtime.InteropServices; + +namespace PasteEx.Library +{ + internal class Kernel32 + { + [DllImport("kernel32.dll", EntryPoint = "GetStdHandle", SetLastError = true, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] + internal static extern IntPtr GetStdHandle(int nStdHandle); + + [DllImport("kernel32.dll", EntryPoint = "AllocConsole", SetLastError = true, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] + internal static extern int AllocConsole(); + + [DllImport("kernel32.dll")] + internal static extern bool AttachConsole(int dwProcessId); + + } +} diff --git a/PasteEx/PasteEx.csproj b/PasteEx/PasteEx.csproj index 76bf725..ef425a9 100644 --- a/PasteEx/PasteEx.csproj +++ b/PasteEx/PasteEx.csproj @@ -64,6 +64,7 @@ + @@ -84,6 +85,7 @@ FormSetting.cs + diff --git a/PasteEx/Program.cs b/PasteEx/Program.cs index ae59ec5..9bc66fe 100644 --- a/PasteEx/Program.cs +++ b/PasteEx/Program.cs @@ -24,9 +24,10 @@ static void Main(string[] args) Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); - + CommandLine.RedirectConsoleOutput(); if (args.Length > 0) { + List commands = new List(args); if (commands[0] == "/reg") { @@ -91,5 +92,6 @@ static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEv Logger.Error(e.ExceptionObject as Exception); MessageBox.Show((e.ExceptionObject as Exception).Message, Resources.Resource_zh_CN.TitleError, MessageBoxButtons.OK, MessageBoxIcon.Error); } + } } diff --git a/PasteEx/Resources/Resource-en-US.Designer.cs b/PasteEx/Resources/Resource-en-US.Designer.cs index 038ae9a..c60665e 100644 --- a/PasteEx/Resources/Resource-en-US.Designer.cs +++ b/PasteEx/Resources/Resource-en-US.Designer.cs @@ -96,6 +96,24 @@ internal static string LblFileNameText { } } + /// + /// 查找类似 Paste As File 的本地化字符串。 + /// + internal static string MenuPasteAsFile { + get { + return ResourceManager.GetString("MenuPasteAsFile", resourceCulture); + } + } + + /// + /// 查找类似 Quick Paste As File 的本地化字符串。 + /// + internal static string MenuQuickPasteAsFile { + get { + return ResourceManager.GetString("MenuQuickPasteAsFile", resourceCulture); + } + } + /// /// 查找类似 剪贴板为空,仍旧进入软件主界面? 的本地化字符串。 /// @@ -106,11 +124,20 @@ internal static string TipAnalyzeFailed { } /// - /// 查找类似 存在相同的文件名,是否覆盖? 的本地化字符串。 + /// 查找类似 The clipboard content is empty or not supported 的本地化字符串。 /// - internal static string TipDuplicateFileName { + internal static string TipAnalyzeFailedWithoutPrompt { get { - return ResourceManager.GetString("TipDuplicateFileName", resourceCulture); + return ResourceManager.GetString("TipAnalyzeFailedWithoutPrompt", resourceCulture); + } + } + + /// + /// 查找类似 Failed to download 的本地化字符串。 + /// + internal static string TipDownloadFailed { + get { + return ResourceManager.GetString("TipDownloadFailed", resourceCulture); } } @@ -150,6 +177,15 @@ internal static string TipPathNotNull { } } + /// + /// 查找类似 Downloading...{0}% 的本地化字符串。 + /// + internal static string TipPictureDownloading { + get { + return ResourceManager.GetString("TipPictureDownloading", resourceCulture); + } + } + /// /// 查找类似 右键菜单添加成功! 的本地化字符串。 /// @@ -159,6 +195,15 @@ internal static string TipRegister { } } + /// + /// 查找类似 规则格式有误,将不被启用 的本地化字符串。 + /// + internal static string TipRulesError { + get { + return ResourceManager.GetString("TipRulesError", resourceCulture); + } + } + /// /// 查找类似 添加右键菜单时,请以管理员的身份运行本软件! 的本地化字符串。 /// @@ -177,6 +222,24 @@ internal static string TipSaveFailed { } } + /// + /// 查找类似 The target file {0} has already existed. Overwrite? 的本地化字符串。 + /// + internal static string TipTargetFileExisted { + get { + return ResourceManager.GetString("TipTargetFileExisted", resourceCulture); + } + } + + /// + /// 查找类似 The target path does not exist 的本地化字符串。 + /// + internal static string TipTargetPathNotExist { + get { + return ResourceManager.GetString("TipTargetPathNotExist", resourceCulture); + } + } + /// /// 查找类似 右键菜单移除成功! 的本地化字符串。 /// @@ -212,5 +275,14 @@ internal static string TitleError { return ResourceManager.GetString("TitleError", resourceCulture); } } + + /// + /// 查找类似 当前你可以使用设置功能 的本地化字符串。 + /// + internal static string TxtCanOnlyUse { + get { + return ResourceManager.GetString("TxtCanOnlyUse", resourceCulture); + } + } } } diff --git a/PasteEx/Resources/Resource-en-US.resx b/PasteEx/Resources/Resource-en-US.resx index aead1f1..108f052 100644 --- a/PasteEx/Resources/Resource-en-US.resx +++ b/PasteEx/Resources/Resource-en-US.resx @@ -129,11 +129,20 @@ File Name: + + Paste As File + + + Quick Paste As File + 剪贴板为空,仍旧进入软件主界面? - - 存在相同的文件名,是否覆盖? + + The clipboard content is empty or not supported + + + Failed to download 你是第一次启动本软件,是否添加“粘贴为文件”到系统右键菜单中? @@ -147,15 +156,27 @@ 文件夹路径不能为空 + + Downloading...{0}% + 右键菜单添加成功! + + 规则格式有误,将不被启用 + 添加右键菜单时,请以管理员的身份运行本软件! 保存失败,请选择正确的扩展名 + + The target file {0} has already existed. Overwrite? + + + The target path does not exist + 右键菜单移除成功! @@ -168,4 +189,7 @@ Error + + 当前你可以使用设置功能 + \ No newline at end of file diff --git a/PasteEx/Resources/Resource-zh-CN.Designer.cs b/PasteEx/Resources/Resource-zh-CN.Designer.cs index 31e74af..9646cb4 100644 --- a/PasteEx/Resources/Resource-zh-CN.Designer.cs +++ b/PasteEx/Resources/Resource-zh-CN.Designer.cs @@ -96,6 +96,24 @@ internal static string LblFileNameText { } } + /// + /// 查找类似 粘贴为文件 的本地化字符串。 + /// + internal static string MenuPasteAsFile { + get { + return ResourceManager.GetString("MenuPasteAsFile", resourceCulture); + } + } + + /// + /// 查找类似 快速粘贴为文件 的本地化字符串。 + /// + internal static string MenuQuickPasteAsFile { + get { + return ResourceManager.GetString("MenuQuickPasteAsFile", resourceCulture); + } + } + /// /// 查找类似 剪贴板内容为空或不被支持,仍旧进入软件主界面? 的本地化字符串。 /// @@ -106,11 +124,20 @@ internal static string TipAnalyzeFailed { } /// - /// 查找类似 存在相同的文件名,是否覆盖? 的本地化字符串。 + /// 查找类似 剪贴板内容为空或不被支持 的本地化字符串。 + /// + internal static string TipAnalyzeFailedWithoutPrompt { + get { + return ResourceManager.GetString("TipAnalyzeFailedWithoutPrompt", resourceCulture); + } + } + + /// + /// 查找类似 下载失败 的本地化字符串。 /// - internal static string TipDuplicateFileName { + internal static string TipDownloadFailed { get { - return ResourceManager.GetString("TipDuplicateFileName", resourceCulture); + return ResourceManager.GetString("TipDownloadFailed", resourceCulture); } } @@ -150,6 +177,15 @@ internal static string TipPathNotNull { } } + /// + /// 查找类似 下载图片中...{0}% 的本地化字符串。 + /// + internal static string TipPictureDownloading { + get { + return ResourceManager.GetString("TipPictureDownloading", resourceCulture); + } + } + /// /// 查找类似 右键菜单添加成功! 的本地化字符串。 /// @@ -186,6 +222,24 @@ internal static string TipSaveFailed { } } + /// + /// 查找类似 目标文件{0}已经存在,是否覆盖? 的本地化字符串。 + /// + internal static string TipTargetFileExisted { + get { + return ResourceManager.GetString("TipTargetFileExisted", resourceCulture); + } + } + + /// + /// 查找类似 粘贴目标路径不存在 的本地化字符串。 + /// + internal static string TipTargetPathNotExist { + get { + return ResourceManager.GetString("TipTargetPathNotExist", resourceCulture); + } + } + /// /// 查找类似 右键菜单移除成功! 的本地化字符串。 /// diff --git a/PasteEx/Resources/Resource-zh-CN.resx b/PasteEx/Resources/Resource-zh-CN.resx index df40fc2..0ae5127 100644 --- a/PasteEx/Resources/Resource-zh-CN.resx +++ b/PasteEx/Resources/Resource-zh-CN.resx @@ -132,9 +132,6 @@ 剪贴板内容为空或不被支持,仍旧进入软件主界面? - - 存在相同的文件名,是否覆盖? - 检测到右键菜单未添加,是否添加“粘贴为文件”到系统右键菜单中? @@ -174,4 +171,25 @@ 系统错误 + + 剪贴板内容为空或不被支持 + + + 目标文件{0}已经存在,是否覆盖? + + + 粘贴目标路径不存在 + + + 粘贴为文件 + + + 快速粘贴为文件 + + + 下载图片中...{0}% + + + 下载失败 + \ No newline at end of file diff --git a/PasteEx/RightMenu.cs b/PasteEx/RightMenu.cs index f638abb..c3f1b46 100644 --- a/PasteEx/RightMenu.cs +++ b/PasteEx/RightMenu.cs @@ -153,13 +153,13 @@ private static void Register( if (fast == FastSetting.False) { - key.SetValue("", Resources.Resource_zh_CN.Title); + key.SetValue("", Resources.Resource_zh_CN.MenuPasteAsFile); cmdKey.SetValue("", Application.ExecutablePath + " \"%V\""); } else { - key.SetValue("", "快速粘贴为文件"); + key.SetValue("", Resources.Resource_zh_CN.MenuQuickPasteAsFile); cmdKey.SetValue("", Application.ExecutablePath + " /q \"%V\""); } @@ -173,12 +173,12 @@ private static void Register( if (fast == FastSetting.False) { - key.SetValue("", Resources.Resource_zh_CN.Title); + key.SetValue("", Resources.Resource_zh_CN.MenuPasteAsFile); cmdKey.SetValue("", Application.ExecutablePath + " \"%1\""); } else { - key.SetValue("", "快速粘贴为文件"); + key.SetValue("", Resources.Resource_zh_CN.MenuQuickPasteAsFile); cmdKey.SetValue("", Application.ExecutablePath + " /q \"%1\""); } } diff --git a/PasteEx/Util/CommandLine.cs b/PasteEx/Util/CommandLine.cs new file mode 100644 index 0000000..f066b4e --- /dev/null +++ b/PasteEx/Util/CommandLine.cs @@ -0,0 +1,36 @@ +using Microsoft.Win32.SafeHandles; +using PasteEx.Library; +using System; +using System.IO; +using System.Text; + +namespace PasteEx.Util +{ + public class CommandLine + { + private const int STD_OUTPUT_HANDLE = -11; + private const int MY_CODE_PAGE = 437; + + private const int ATTACH_PARENT_PROCESS = -1; + + public static void RedirectConsoleOutput() + { + Kernel32.AttachConsole(ATTACH_PARENT_PROCESS); + } + + /// + /// not used + /// + public static void NewConsole() + { + Kernel32.AllocConsole(); + IntPtr stdHandle = Kernel32.GetStdHandle(STD_OUTPUT_HANDLE); + SafeFileHandle safeFileHandle = new SafeFileHandle(stdHandle, true); + FileStream fileStream = new FileStream(safeFileHandle, FileAccess.Write); + Encoding encoding = Encoding.GetEncoding(MY_CODE_PAGE); + StreamWriter standardOutput = new StreamWriter(fileStream, encoding); + standardOutput.AutoFlush = true; + Console.SetOut(standardOutput); + } + } +}