From 7b5c3eea84a2c6263e6f6c1c64d697e5684759dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E8=82=A5=E7=BE=8A?= <1048382248@qq.com> Date: Thu, 18 Apr 2024 10:37:40 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=A1=B9=E7=9B=AE=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .config/dotnet-tools.json | 12 + AsposeHook/Aspose, Windows V23.12.0.0.txt | 1 + AsposeHook/HookManager.cs | 419 ++++++++++++++++++++++ AsposeHook/Kernel32.cs | 15 + AsposeHook/MethodHook.cs | 237 ++++++++++++ AsposeHook/MethodMeta.cs | 32 ++ AsposeHook/Utils.cs | 105 ++++++ AsposeWordManage.cs | 93 +++++ Controllers/PdfController.cs | 50 +++ Controllers/WordController.cs | 62 ++++ CustomExceptionFilter.cs | 27 ++ LearnWordManage.csproj | 21 ++ LearnWordManage.sln | 25 ++ Program.cs | 40 +++ Properties/launchSettings.json | 31 ++ appsettings.Development.json | 8 + appsettings.json | 9 + runtimeconfig.json | 7 + 18 files changed, 1194 insertions(+) create mode 100644 .config/dotnet-tools.json create mode 100644 AsposeHook/Aspose, Windows V23.12.0.0.txt create mode 100644 AsposeHook/HookManager.cs create mode 100644 AsposeHook/Kernel32.cs create mode 100644 AsposeHook/MethodHook.cs create mode 100644 AsposeHook/MethodMeta.cs create mode 100644 AsposeHook/Utils.cs create mode 100644 AsposeWordManage.cs create mode 100644 Controllers/PdfController.cs create mode 100644 Controllers/WordController.cs create mode 100644 CustomExceptionFilter.cs create mode 100644 LearnWordManage.csproj create mode 100644 LearnWordManage.sln create mode 100644 Program.cs create mode 100644 Properties/launchSettings.json create mode 100644 appsettings.Development.json create mode 100644 appsettings.json create mode 100644 runtimeconfig.json diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json new file mode 100644 index 0000000..d9d129c --- /dev/null +++ b/.config/dotnet-tools.json @@ -0,0 +1,12 @@ +{ + "version": 1, + "isRoot": true, + "tools": { + "dotnet-ef": { + "version": "8.0.3", + "commands": [ + "dotnet-ef" + ] + } + } +} \ No newline at end of file diff --git a/AsposeHook/Aspose, Windows V23.12.0.0.txt b/AsposeHook/Aspose, Windows V23.12.0.0.txt new file mode 100644 index 0000000..d493d34 --- /dev/null +++ b/AsposeHook/Aspose, Windows V23.12.0.0.txt @@ -0,0 +1 @@ +windows \ No newline at end of file diff --git a/AsposeHook/HookManager.cs b/AsposeHook/HookManager.cs new file mode 100644 index 0000000..59c2c95 --- /dev/null +++ b/AsposeHook/HookManager.cs @@ -0,0 +1,419 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.Serialization; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading; +using System.Threading.Tasks; +using System.Xml; + +namespace ExtractResFile.AsposeHook +{ + public static class HookManager + { + private static MethodHook mCompareHook; + + private static MethodHook mGreaterThanHook; + + private static MethodHook mParseExactHook; + + private static MethodHook mInnerTextHook; + + private static MethodHook mIndexOfHook; + + private static MethodHook mStringSplitHook; + + private static MethodHook mMethodInvokeHook; + + private static List mAssembliesLicenseSetted = new List(); + + private static List mMethodHookList = new List(); + + private static readonly string DATE_CHANGED_TO = DateTime.Today.Year + 1 + "0827"; + + private const string LICENSE_STRING = "PExpY2Vuc2U+CiAgPERhdGE+CiAgICA8TGljZW5zZWRUbz5TdXpob3UgQXVuYm94IFNvZnR3YXJlIENvLiwgTHRkLjwvTGljZW5zZWRUbz4KICAgIDxFbWFpbFRvPnNhbGVzQGF1bnRlYy5jb208L0VtYWlsVG8+CiAgICA8TGljZW5zZVR5cGU+RGV2ZWxvcGVyIE9FTTwvTGljZW5zZVR5cGU+CiAgICA8TGljZW5zZU5vdGU+TGltaXRlZCB0byAxIGRldmVsb3BlciwgdW5saW1pdGVkIHBoeXNpY2FsIGxvY2F0aW9uczwvTGljZW5zZU5vdGU+CiAgICA8T3JkZXJJRD4xOTA4MjYwODA3NTM8L09yZGVySUQ+CiAgICA8VXNlcklEPjEzNDk3NjAwNjwvVXNlcklEPgogICAgPE9FTT5UaGlzIGlzIGEgcmVkaXN0cmlidXRhYmxlIGxpY2Vuc2U8L09FTT4KICAgIDxQcm9kdWN0cz4KICAgICAgPFByb2R1Y3Q+QXNwb3NlLlRvdGFsIGZvciAuTkVUPC9Qcm9kdWN0PgogICAgPC9Qcm9kdWN0cz4KICAgIDxFZGl0aW9uVHlwZT5FbnRlcnByaXNlPC9FZGl0aW9uVHlwZT4KICAgIDxTZXJpYWxOdW1iZXI+M2U0NGRlMzAtZmNkMi00MTA2LWIzNWQtNDZjNmEzNzE1ZmMyPC9TZXJpYWxOdW1iZXI+CiAgICA8U3Vic2NyaXB0aW9uRXhwaXJ5PjIwMjAwODI3PC9TdWJzY3JpcHRpb25FeHBpcnk+CiAgICA8TGljZW5zZVZlcnNpb24+My4wPC9MaWNlbnNlVmVyc2lvbj4KICAgIDxMaWNlbnNlSW5zdHJ1Y3Rpb25zPmh0dHBzOi8vcHVyY2hhc2UuYXNwb3NlLmNvbS9wb2xpY2llcy91c2UtbGljZW5zZTwvTGljZW5zZUluc3RydWN0aW9ucz4KICA8L0RhdGE+CiAgPFNpZ25hdHVyZT53UGJtNUt3ZTYvRFZXWFNIY1o4d2FiVEFQQXlSR0pEOGI3L00zVkV4YWZpQnd5U2h3YWtrNGI5N2c2eGtnTjhtbUFGY3J0c0cwd1ZDcnp6MytVYk9iQjRYUndTZWxsTFdXeXNDL0haTDNpN01SMC9jZUFxaVZFOU0rWndOQkR4RnlRbE9uYTFQajhQMzhzR1grQ3ZsemJLZFZPZXk1S3A2dDN5c0dqYWtaL1E9PC9TaWduYXR1cmU+CjwvTGljZW5zZT4="; + + private static void Initialize() + { + if (mMethodHookList.Count == 0) + { + try + { + MethodInfo method = typeof(MethodBase).GetMethod("Invoke", BindingFlags.Instance | BindingFlags.Public, null, new Type[2] + { + typeof(object), + typeof(object[]) + }, null); + MethodInfo method2 = typeof(HookManager).GetMethod("NewMethodInvoke", BindingFlags.Static | BindingFlags.Public, null, new Type[3] + { + typeof(MethodBase), + typeof(object), + typeof(object[]) + }, null); + mMethodInvokeHook = new MethodHook(method, method2); + mMethodHookList.Add(mMethodInvokeHook); + } + catch (Exception ex) + { + Utils.LogWriteLine("Initialize method XmlElement.InnerText.Get error:" + ex.Message, ConsoleColor.DarkRed); + } + + try + { + MethodInfo method3 = typeof(DateTime).GetMethod("ParseExact", BindingFlags.Static | BindingFlags.Public, null, new Type[3] + { + typeof(string), + typeof(string), + typeof(IFormatProvider) + }, null); + MethodInfo method4 = typeof(HookManager).GetMethod("NewParseExact", BindingFlags.Static | BindingFlags.Public, null, new Type[3] + { + typeof(string), + typeof(string), + typeof(IFormatProvider) + }, null); + mParseExactHook = new MethodHook(method3, method4); + } + catch (Exception ex2) + { + Utils.LogWriteLine("Initialize method DateTime.ParseExact error:" + ex2.Message, ConsoleColor.DarkRed); + } + + try + { + MethodInfo method5 = typeof(DateTime).GetMethod("op_GreaterThan", BindingFlags.Static | BindingFlags.Public, null, new Type[2] + { + typeof(DateTime), + typeof(DateTime) + }, null); + MethodInfo method6 = typeof(HookManager).GetMethod("NewGreaterThan", BindingFlags.Static | BindingFlags.Public, null, new Type[2] + { + typeof(DateTime), + typeof(DateTime) + }, null); + mGreaterThanHook = new MethodHook(method5, method6); + } + catch (Exception ex3) + { + Utils.LogWriteLine("Initialize method DateTime.op_GreaterThan error:" + ex3.Message, ConsoleColor.DarkRed); + } + + try + { + MethodInfo method7 = typeof(string).GetMethod("Compare", BindingFlags.Static | BindingFlags.Public, null, new Type[2] + { + typeof(string), + typeof(string) + }, null); + MethodInfo method8 = typeof(HookManager).GetMethod("NewCompare", BindingFlags.Static | BindingFlags.Public, null, new Type[2] + { + typeof(string), + typeof(string) + }, null); + mCompareHook = new MethodHook(method7, method8); + mMethodHookList.Add(mCompareHook); + } + catch (Exception ex4) + { + Utils.LogWriteLine("Initialize method string.Compare error:" + ex4.Message, ConsoleColor.DarkRed); + } + + try + { + MethodInfo method9 = typeof(string).GetMethod("IndexOf", BindingFlags.Instance | BindingFlags.Public, null, new Type[1] { typeof(string) }, null); + MethodInfo method10 = typeof(HookManager).GetMethod("NewIndexOf", BindingFlags.Static | BindingFlags.Public, null, new Type[2] + { + typeof(string), + typeof(string) + }, null); + mIndexOfHook = new MethodHook(method9, method10); + } + catch (Exception ex5) + { + Utils.LogWriteLine("Initialize method string.IndexOf error:" + ex5.Message, ConsoleColor.DarkRed); + } + + try + { + MethodInfo getMethod = typeof(XmlElement).GetProperty("InnerText", BindingFlags.Instance | BindingFlags.Public).GetMethod; + MethodInfo method11 = typeof(HookManager).GetMethod("NewInnerText", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(XmlElement) }, null); + mInnerTextHook = new MethodHook(getMethod, method11); + } + catch (Exception ex6) + { + Utils.LogWriteLine("Initialize method XmlElement.InnerText.Get error:" + ex6.Message, ConsoleColor.DarkRed); + } + + try + { + MethodInfo method12 = typeof(string).GetMethod("Split", BindingFlags.Instance | BindingFlags.Public, null, new Type[1] { typeof(char[]) }, null); + MethodInfo method13 = typeof(HookManager).GetMethod("NewStringSplitForNET4", BindingFlags.Static | BindingFlags.Public, null, new Type[2] + { + typeof(string), + typeof(char[]) + }, null); + mStringSplitHook = new MethodHook(method12, method13); + } + catch (Exception ex7) + { + Utils.LogWriteLine("Initialize method string.Split error:" + ex7.Message, ConsoleColor.DarkRed); + } + } + } + + public static void ShowHookDetails(bool show) + { + if (show) + { + Utils.EnableLog(); + } + else + { + Utils.DisableLog(); + } + } + + public static void StartHook() + { + try + { + Initialize(); + mMethodHookList.ForEach(delegate (MethodHook item) + { + item?.StartHook(); + }); + IEnumerable enumerable = (from assembly in Assembly.GetCallingAssembly()?.GetReferencedAssemblies().Union(Assembly.GetEntryAssembly()?.GetReferencedAssemblies() ?? new AssemblyName[0]) + group assembly by assembly.Name into item + select item.FirstOrDefault() into assembly + where assembly.Name.StartsWith("Aspose") && !assembly.Name.StartsWith("Aspose.Hook") + select assembly); + if (enumerable == null) + { + return; + } + + foreach (AssemblyName item in enumerable) + { + if (!mAssembliesLicenseSetted.Contains(item.FullName)) + { + Type type = Assembly.Load(item).GetType(item.Name + ".License"); + if (type == null) + { + type = Assembly.Load(item).GetType(Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(item.Name.ToLower()) + ".License"); + } + + if (type != null) + { + Utils.LogWriteLine("\nSETTING..." + type.FullName, ConsoleColor.Yellow); + object obj = Activator.CreateInstance(type); + MethodInfo? method = type.GetMethod("SetLicense", new Type[1] { typeof(Stream) }); + object[] parameters = new MemoryStream[1] + { + new MemoryStream(Convert.FromBase64String("PExpY2Vuc2U+CiAgPERhdGE+CiAgICA8TGljZW5zZWRUbz5TdXpob3UgQXVuYm94IFNvZnR3YXJlIENvLiwgTHRkLjwvTGljZW5zZWRUbz4KICAgIDxFbWFpbFRvPnNhbGVzQGF1bnRlYy5jb208L0VtYWlsVG8+CiAgICA8TGljZW5zZVR5cGU+RGV2ZWxvcGVyIE9FTTwvTGljZW5zZVR5cGU+CiAgICA8TGljZW5zZU5vdGU+TGltaXRlZCB0byAxIGRldmVsb3BlciwgdW5saW1pdGVkIHBoeXNpY2FsIGxvY2F0aW9uczwvTGljZW5zZU5vdGU+CiAgICA8T3JkZXJJRD4xOTA4MjYwODA3NTM8L09yZGVySUQ+CiAgICA8VXNlcklEPjEzNDk3NjAwNjwvVXNlcklEPgogICAgPE9FTT5UaGlzIGlzIGEgcmVkaXN0cmlidXRhYmxlIGxpY2Vuc2U8L09FTT4KICAgIDxQcm9kdWN0cz4KICAgICAgPFByb2R1Y3Q+QXNwb3NlLlRvdGFsIGZvciAuTkVUPC9Qcm9kdWN0PgogICAgPC9Qcm9kdWN0cz4KICAgIDxFZGl0aW9uVHlwZT5FbnRlcnByaXNlPC9FZGl0aW9uVHlwZT4KICAgIDxTZXJpYWxOdW1iZXI+M2U0NGRlMzAtZmNkMi00MTA2LWIzNWQtNDZjNmEzNzE1ZmMyPC9TZXJpYWxOdW1iZXI+CiAgICA8U3Vic2NyaXB0aW9uRXhwaXJ5PjIwMjAwODI3PC9TdWJzY3JpcHRpb25FeHBpcnk+CiAgICA8TGljZW5zZVZlcnNpb24+My4wPC9MaWNlbnNlVmVyc2lvbj4KICAgIDxMaWNlbnNlSW5zdHJ1Y3Rpb25zPmh0dHBzOi8vcHVyY2hhc2UuYXNwb3NlLmNvbS9wb2xpY2llcy91c2UtbGljZW5zZTwvTGljZW5zZUluc3RydWN0aW9ucz4KICA8L0RhdGE+CiAgPFNpZ25hdHVyZT53UGJtNUt3ZTYvRFZXWFNIY1o4d2FiVEFQQXlSR0pEOGI3L00zVkV4YWZpQnd5U2h3YWtrNGI5N2c2eGtnTjhtbUFGY3J0c0cwd1ZDcnp6MytVYk9iQjRYUndTZWxsTFdXeXNDL0haTDNpN01SMC9jZUFxaVZFOU0rWndOQkR4RnlRbE9uYTFQajhQMzhzR1grQ3ZsemJLZFZPZXk1S3A2dDN5c0dqYWtaL1E9PC9TaWduYXR1cmU+CjwvTGljZW5zZT4=")) + }; + method.Invoke(obj, BindingFlags.Instance | BindingFlags.Public, null, parameters, null); + Utils.LogWriteLine(type.FullName + " SET SUCCESSFULLY.", ConsoleColor.Yellow); + mAssembliesLicenseSetted.Add(item.FullName); + } + } + } + } + catch (Exception ex) + { + Exception ex2 = ex; + while (ex2.InnerException != null) + { + ex2 = ex2.InnerException; + } + + Utils.LogWriteLine("start hook failed because of " + ex2.Message + ".", ConsoleColor.Red); + } + } + + public static void StopHook() + { + mMethodHookList.ForEach(delegate (MethodHook item) + { + item?.StopHook(); + }); + } + + public static object NewMethodInvoke(MethodBase method, object obj, object[] parameters) + { + if (Assembly.GetCallingAssembly() != null && Assembly.GetCallingAssembly().FullName.StartsWith("Aspose.") && method.Name == "ParseExact" && parameters.Length != 0 && parameters[0].ToString().Contains("0827")) + { + DateTime dateTime = DateTime.ParseExact(DATE_CHANGED_TO, "yyyyMMdd", CultureInfo.InvariantCulture); + ShowLog(method, dateTime, obj, parameters); + return dateTime; + } + + if (Assembly.GetCallingAssembly() != null && Assembly.GetCallingAssembly().FullName.StartsWith("Aspose.") && method.Name == "ParseExact" && parameters.Length != 0 && parameters[0].ToString() == DateTime.Now.ToString("yyyy.MM.01")) + { + DateTime dateTime2 = DateTime.ParseExact("20200501", "yyyyMMdd", CultureInfo.InvariantCulture); + ShowLog(method, dateTime2, obj, parameters); + return dateTime2; + } + + if (Assembly.GetCallingAssembly() != null && Assembly.GetCallingAssembly().FullName.StartsWith("Aspose.") && method.Name == "get_InnerText1" && obj is XmlElement && (obj as XmlElement).Name == "SubscriptionExpiry") + { + ShowLog(method, DATE_CHANGED_TO, obj, parameters); + return DATE_CHANGED_TO; + } + + if (Assembly.GetCallingAssembly() != null && Assembly.GetCallingAssembly().FullName.StartsWith("Aspose.") && method.Name == "get_Ticks" && obj is DateTime dateTime3 && dateTime3.ToString("MMdd") == "0827") + { + long ticks = DateTime.ParseExact(DATE_CHANGED_TO, "yyyyMMdd", CultureInfo.InvariantCulture).Ticks; + ShowLog(method, ticks, obj, parameters); + return ticks; + } + + if (Assembly.GetCallingAssembly() != null && Assembly.GetCallingAssembly().FullName.StartsWith("Aspose.") && method.Name == "Compare") + { + return DATE_CHANGED_TO; + } + + if (Assembly.GetCallingAssembly() != null && Assembly.GetCallingAssembly().FullName.StartsWith("Aspose.") && method.Name == "op_GreaterThan" && parameters.Length == 2 && parameters[1] is DateTime && ((DateTime)parameters[1]).ToString("MMdd") == "0827") + { + ShowLog(method, false, obj, parameters); + return false; + } + + if (Assembly.GetCallingAssembly() != null && Assembly.GetCallingAssembly().FullName.StartsWith("Aspose.") && method.Name == "IndexOf" && parameters.Length != 0 && parameters[0].ToString().Contains("0827")) + { + ShowLog(method, 580, obj, parameters); + return 580; + } + + if (Assembly.GetCallingAssembly() != null && Assembly.GetCallingAssembly().FullName.StartsWith("Aspose.") && method.Name == "Split" && Regex.Match(obj.ToString(), "^\\d{4}\\.\\d{2}\\.\\d{2}$").Success && obj != null && obj.ToString().Substring(0, 4) == DateTime.Now.Year.ToString()) + { + ShowLog(method, "new string[] { \"2019\", \"08\", \"27\" }", obj, parameters); + return new string[3] { "2019", "08", "27" }; + } + + if (Assembly.GetCallingAssembly() != null && Assembly.GetCallingAssembly().FullName.StartsWith("Aspose.") && method.Name == "get_Now") + { + DateTime dateTime4 = DateTime.ParseExact("20200518", "yyyyMMdd", CultureInfo.InvariantCulture); + ShowLog(method, dateTime4, obj, parameters); + return dateTime4; + } + + return mMethodInvokeHook.InvokeOriginal(method, new object[2] + { + obj, + parameters.ToArray() + }); + } + + private static void ShowLog(MethodBase method, object ret, object obj, object[] parameters) + { + if (method.Name == "GetBytes" || method.Name == "GetManifestResourceNames" || method.Name == "get_DocumentElement" || method.Name == "get_FirstChild" || method.Name == "op_Equality" || method.Name == "get_LocalName" || method.Name == "Append" || method.Name == "get_Chars" || method.Name == "Write" || method.Name == "get_Length" || method.Name == "WriteByte" || (obj == null && parameters.Length == 1 && parameters[0] is int && (int)parameters[0] < 0)) + { + return; + } + + string empty = string.Empty; + try + { + empty = ((obj is Stream || parameters == null || parameters.Length == 0 || parameters.Where((object item) => item is Stream || item is StreamingContext).Count() != 0) ? (obj?.ToString() + "," + parameters) : (JsonConvert.SerializeObject(obj) + "," + JsonConvert.SerializeObject((object)parameters))); + } + catch (Exception) + { + empty = obj?.ToString() + "," + parameters; + } + + string empty2 = string.Empty; + try + { + empty2 = ((!(ret is Stream)) ? JsonConvert.SerializeObject(ret) : "..."); + } + catch (Exception) + { + empty2 = ret.ToString(); + } + + Utils.LogWriteLine("INVOKE method " + method.Name + "(" + empty + ") RETURN=> " + empty2, ConsoleColor.DarkGray); + } + + public static int NewCompare(string s1, string s2) + { + if (Assembly.GetCallingAssembly() != null && Assembly.GetCallingAssembly().FullName.StartsWith("Aspose.") && s2 == "20200827") + { + Utils.LogWriteLine("HOOK SUCCESS: From " + Assembly.GetCallingAssembly().GetName().Name + " String.Compare(" + s1 + "," + s2 + ") return -1;", ConsoleColor.Green); + return -1; + } + + return mCompareHook.InvokeOriginal(null, new object[2] { s1, s2 }); + } + + public static bool NewGreaterThan(DateTime t1, DateTime t2) + { + if (Assembly.GetCallingAssembly() != null && Assembly.GetCallingAssembly().FullName.StartsWith("Aspose.") && t2.ToString("yyyyMMdd") == "20200827") + { + Utils.LogWriteLine($"HOOK SUCCESS: From {Assembly.GetCallingAssembly().GetName().Name} DateTime ({t1}>{t2}) return false;", ConsoleColor.Green); + return false; + } + + return mGreaterThanHook.InvokeOriginal(null, new object[2] { t1, t2 }); + } + + public static DateTime NewParseExact(string s, string format, IFormatProvider provider) + { + if (Assembly.GetCallingAssembly() != null && Assembly.GetCallingAssembly().FullName.StartsWith("Aspose.") && s == "20200827") + { + Utils.LogWriteLine($"HOOK SUCCESS: From {Assembly.GetCallingAssembly().GetName().Name} DateTime.ParseExact({s},{format},{provider}) return {DATE_CHANGED_TO};", ConsoleColor.Green); + return mParseExactHook.InvokeOriginal(null, new object[3] { DATE_CHANGED_TO, format, provider }); + } + + return mParseExactHook.InvokeOriginal(null, new object[3] { s, format, provider }); + } + + public static string NewInnerText(XmlElement element) + { + if (Assembly.GetCallingAssembly() != null && Assembly.GetCallingAssembly().FullName.StartsWith("Aspose.") && !Assembly.GetCallingAssembly().FullName.StartsWith("Aspose.Words") && !Assembly.GetCallingAssembly().FullName.StartsWith("Aspose.Hook") && element.Name == "SubscriptionExpiry") + { + Utils.LogWriteLine("HOOK SUCCESS: From " + Assembly.GetCallingAssembly().GetName().Name + " XmlElement.InnerText (" + element.Name + "," + element.InnerXml + ") return " + DATE_CHANGED_TO + ";", ConsoleColor.Green); + return DATE_CHANGED_TO; + } + + return mInnerTextHook.InvokeOriginal(element, Array.Empty()); + } + + public static int NewIndexOf(string v1, string v2) + { + if (Assembly.GetCallingAssembly() != null && Assembly.GetCallingAssembly().FullName.StartsWith("Aspose.") && v2 == DATE_CHANGED_TO) + { + Utils.LogWriteLine("HOOK SUCCESS: From " + Assembly.GetCallingAssembly().GetName().Name + " " + v1.ToString().Substring(0, 9) + "....IndexOf(" + v2 + ") return 580;", ConsoleColor.Green); + return 580; + } + + return mIndexOfHook.InvokeOriginal(v1, new object[1] { v2 }); + } + + public static string[] NewStringSplitForNET6(string value, char separator, StringSplitOptions options) + { + if (Assembly.GetCallingAssembly() != null && Assembly.GetCallingAssembly().FullName.StartsWith("Aspose.") && value != null && value.Length == 10 && Regex.Match(value, "^\\d{4}\\.\\d{2}\\.\\d{2}$").Success && separator == '.' && options == StringSplitOptions.None) + { + Utils.LogWriteLine($"HOOK SUCCESS: From {Assembly.GetCallingAssembly().GetName().Name} String.Split({value},{separator}) return 20190827;", ConsoleColor.Green); + return new string[3] { "2019", "08", "27" }; + } + + return mStringSplitHook.InvokeOriginal(value, new object[2] { separator, options }); + } + + public static string[] NewStringSplitForNET4(string value, char[] separator) + { + if (Assembly.GetCallingAssembly() != null && Assembly.GetCallingAssembly().FullName.StartsWith("Aspose.") && value != null && value.Length == 10 && Regex.Match(value, "^\\d{4}\\.\\d{2}\\.\\d{2}$").Success && separator != null && separator.Length != 0 && separator[0] == '.') + { + Utils.LogWriteLine($"HOOK SUCCESS: From {Assembly.GetCallingAssembly().GetName().Name} String.Split({value},{separator}) return 20190827;", ConsoleColor.Green); + return new string[3] { "2019", "08", "27" }; + } + + return mStringSplitHook.InvokeOriginal(value, new object[1] { separator }); + } + } +} diff --git a/AsposeHook/Kernel32.cs b/AsposeHook/Kernel32.cs new file mode 100644 index 0000000..0fa17e5 --- /dev/null +++ b/AsposeHook/Kernel32.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace ExtractResFile.AsposeHook +{ + internal static class Kernel32 + { + [DllImport("kernel32.dll", SetLastError = true)] + internal static extern bool VirtualProtect(IntPtr baseAddress, int protectionSize, uint protectionType, out uint oldProtectionType); + } +} diff --git a/AsposeHook/MethodHook.cs b/AsposeHook/MethodHook.cs new file mode 100644 index 0000000..b038322 --- /dev/null +++ b/AsposeHook/MethodHook.cs @@ -0,0 +1,237 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace ExtractResFile.AsposeHook +{ + public class MethodHook + { + private byte[] _jmpCodeBytes; + + private byte[] _originalMethodBytes; + + private MethodMeta _sourceMethodMeta; + + private MethodMeta _targetMethodMeta; + + private bool _hookInitialized = false; + + public bool IsEnabled { get; protected set; } + + public MethodHook(MethodBase sourceMethod, MethodBase targetMethod) + { + if (sourceMethod == null) + { + throw new ArgumentException("create source method hook failed because of method is null."); + } + + if (targetMethod == null) + { + throw new ArgumentException("create target method hook failed because of method is null."); + } + + try + { + _sourceMethodMeta = new MethodMeta + { + Method = sourceMethod + }; + _targetMethodMeta = new MethodMeta + { + Method = targetMethod + }; + PrepareHook(); + _hookInitialized = true; + Utils.LogWriteLine(_sourceMethodMeta.Method.DeclaringType.FullName + "." + _sourceMethodMeta.Method.Name + " is to be HOOKED by " + _targetMethodMeta.Method.Name + ".\n", ConsoleColor.DarkYellow); + } + catch (Exception) + { + _hookInitialized = false; + } + + IsEnabled = false; + } + + public void StartHook(bool showInfo = true) + { + try + { + if (!IsEnabled && _hookInitialized) + { + Kernel32.VirtualProtect(_sourceMethodMeta.FinalMethodAddress, _jmpCodeBytes.Length, 64u, out var oldProtectionType); + Marshal.Copy(_jmpCodeBytes, 0, _sourceMethodMeta.FinalMethodAddress, _jmpCodeBytes.Length); + Kernel32.VirtualProtect(_sourceMethodMeta.FinalMethodAddress, _jmpCodeBytes.Length, oldProtectionType, out var _); + IsEnabled = true; + if (showInfo) + { + Utils.LogWriteLine(_sourceMethodMeta.Method.Name + " HOOK STARTED.", ConsoleColor.Blue); + } + } + } + catch (Exception ex) + { + Utils.LogWriteLine(_sourceMethodMeta.Method.Name + " start hook error:" + ex.Message, ConsoleColor.DarkRed); + } + } + + public void StopHook(bool showInfo = true) + { + try + { + if (IsEnabled && _hookInitialized) + { + Kernel32.VirtualProtect(_sourceMethodMeta.FinalMethodAddress, _originalMethodBytes.Length, 64u, out var oldProtectionType); + Marshal.Copy(_originalMethodBytes, 0, _sourceMethodMeta.FinalMethodAddress, _originalMethodBytes.Length); + Kernel32.VirtualProtect(_sourceMethodMeta.FinalMethodAddress, _originalMethodBytes.Length, oldProtectionType, out var _); + IsEnabled = false; + if (showInfo) + { + Utils.LogWriteLine(_sourceMethodMeta.Method.Name + " HOOK STOPPED.", ConsoleColor.Red); + } + } + } + catch (Exception ex) + { + Utils.LogWriteLine(_sourceMethodMeta.Method.Name + " stop hook error:" + ex.Message, ConsoleColor.DarkRed); + } + } + + private void PrepareHook() + { + _sourceMethodMeta.MethodDescAddress = _sourceMethodMeta.Method.MethodHandle.Value; + _sourceMethodMeta.MethodDescValue = _sourceMethodMeta.Method.MethodHandle.Value.ReadIntPtr(); + _sourceMethodMeta.FunctionPointerBeforePrepare = _sourceMethodMeta.Method.MethodHandle.GetFunctionPointer(); + _sourceMethodMeta.Next1IntptrBeforePrepare = (_sourceMethodMeta.Method.MethodHandle.Value + IntPtr.Size).ReadIntPtr(); + _sourceMethodMeta.Next2IntptrBeforePrepare = (_sourceMethodMeta.Method.MethodHandle.Value + IntPtr.Size * 2).ReadIntPtr(); + RuntimeHelpers.PrepareMethod(_sourceMethodMeta.Method.MethodHandle); + _sourceMethodMeta.FunctionPointerAfterPrepare = _sourceMethodMeta.Method.MethodHandle.GetFunctionPointer(); + _sourceMethodMeta.Next1IntptrAfterPrepare = (_sourceMethodMeta.Method.MethodHandle.Value + IntPtr.Size).ReadIntPtr(); + _sourceMethodMeta.Next2IntptrAfterPrepare = (_sourceMethodMeta.Method.MethodHandle.Value + IntPtr.Size * 2).ReadIntPtr(); + Utils.ShowMethodInfo(_sourceMethodMeta); + if (Environment.Is64BitProcess) + { + Utils.LogWriteLine("Because of Environment.Is64BitProcess, change method " + _sourceMethodMeta.Method.Name + " PREJIT to JIT through add 0x20."); + Marshal.WriteByte(_sourceMethodMeta.Method.MethodHandle.Value + 7, 32); + Utils.LogWriteLine("method " + _sourceMethodMeta.Method.Name + " MD value has changed to:" + _sourceMethodMeta.Method.MethodHandle.Value.ReadIntPtr().To16String()); + } + + _sourceMethodMeta.FinalMethodAddress = _sourceMethodMeta.FunctionPointerAfterPrepare; + Utils.LogWriteLine("Finally, wo choose method " + _sourceMethodMeta.Method.Name + " address: " + _sourceMethodMeta.FinalMethodAddress.To16String()); + _targetMethodMeta.MethodDescAddress = _targetMethodMeta.Method.MethodHandle.Value; + _targetMethodMeta.MethodDescValue = _targetMethodMeta.Method.MethodHandle.Value.ReadIntPtr(); + _targetMethodMeta.FunctionPointerBeforePrepare = _targetMethodMeta.Method.MethodHandle.GetFunctionPointer(); + _targetMethodMeta.Next1IntptrBeforePrepare = (_targetMethodMeta.Method.MethodHandle.Value + IntPtr.Size).ReadIntPtr(); + _targetMethodMeta.Next2IntptrBeforePrepare = (_targetMethodMeta.Method.MethodHandle.Value + IntPtr.Size * 2).ReadIntPtr(); + RuntimeHelpers.PrepareMethod(_targetMethodMeta.Method.MethodHandle); + _targetMethodMeta.FunctionPointerAfterPrepare = _targetMethodMeta.Method.MethodHandle.GetFunctionPointer(); + _targetMethodMeta.Next1IntptrAfterPrepare = (_targetMethodMeta.Method.MethodHandle.Value + IntPtr.Size).ReadIntPtr(); + _targetMethodMeta.Next2IntptrAfterPrepare = (_targetMethodMeta.Method.MethodHandle.Value + IntPtr.Size * 2).ReadIntPtr(); + Utils.ShowMethodInfo(_targetMethodMeta); + _targetMethodMeta.FinalMethodAddress = _targetMethodMeta.FunctionPointerAfterPrepare; + Utils.LogWriteLine("Finally, wo choose method " + _targetMethodMeta.Method.Name + " address: " + _targetMethodMeta.FinalMethodAddress.To16String()); + Utils.LogWriteLine("Now change method " + _sourceMethodMeta.Method.Name + " body to jump to " + _targetMethodMeta.Method.Name + " through jmp instuction..."); + List list = new List(); + if (Environment.Is64BitProcess) + { + list.AddRange(new byte[2] { 72, 184 }); + list.AddRange(BitConverter.GetBytes((long)_targetMethodMeta.FinalMethodAddress)); + list.AddRange(new byte[2] { 255, 224 }); + } + else + { + list.Add(184); + list.AddRange(BitConverter.GetBytes((int)_targetMethodMeta.FinalMethodAddress)); + list.AddRange(new byte[2] { 255, 224 }); + } + + _jmpCodeBytes = list.ToArray(); + _originalMethodBytes = new byte[_jmpCodeBytes.Length]; + Kernel32.VirtualProtect(_sourceMethodMeta.FinalMethodAddress, _jmpCodeBytes.Length, 64u, out var oldProtectionType); + Marshal.Copy(_sourceMethodMeta.FinalMethodAddress, _originalMethodBytes, 0, _jmpCodeBytes.Length); + Kernel32.VirtualProtect(_sourceMethodMeta.FinalMethodAddress, _jmpCodeBytes.Length, oldProtectionType, out var _); + } + + public T InvokeOriginal(object instance, params object[] args) + { + try + { + if (IsEnabled) + { + if (instance is MethodBase) + { + object obj = (instance as MethodBase).Invoke(args[0], BindingFlags.Default, null, args[1] as object[], null); + if ((object)typeof(T) != null) + { + return (T)obj; + } + + return (T)Convert.ChangeType(obj, typeof(T)); + } + + StopHook(showInfo: false); + object obj2 = _sourceMethodMeta.Method.Invoke(instance, args); + StartHook(showInfo: false); + if ((object)typeof(T) != null) + { + return (T)obj2; + } + + return (T)Convert.ChangeType(obj2, typeof(T)); + } + + object value = _sourceMethodMeta.Method.Invoke(instance, args); + return (T)Convert.ChangeType(value, typeof(T)); + } + catch (Exception ex) + { + Exception ex2 = ex; + while (ex2.InnerException != null) + { + ex2 = ex2.InnerException; + } + + Utils.LogWriteLine("call InvokeOriginal error:" + ex2.Message, ConsoleColor.DarkRed); + } + + return default(T); + } + + public void InvokeOriginal(object instance, params object[] args) + { + try + { + if (IsEnabled) + { + if (instance is MethodBase) + { + (instance as MethodBase).Invoke(args[0], BindingFlags.Default, null, args[1] as object[], null); + return; + } + + StopHook(showInfo: false); + _sourceMethodMeta.Method.Invoke(instance, args); + StartHook(showInfo: false); + } + else + { + _sourceMethodMeta.Method.Invoke(instance, args); + } + } + catch (Exception ex) + { + Exception ex2 = ex; + while (ex2.InnerException != null) + { + ex2 = ex2.InnerException; + } + + Utils.LogWriteLine("call InvokeOriginal error:" + ex2.Message, ConsoleColor.DarkRed); + } + } + } +} diff --git a/AsposeHook/MethodMeta.cs b/AsposeHook/MethodMeta.cs new file mode 100644 index 0000000..a480599 --- /dev/null +++ b/AsposeHook/MethodMeta.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace ExtractResFile.AsposeHook +{ + internal class MethodMeta + { + public MethodBase Method { get; set; } + + public IntPtr MethodDescAddress { get; set; } + + public IntPtr MethodDescValue { get; set; } + + public IntPtr FunctionPointerBeforePrepare { get; set; } + + public IntPtr Next1IntptrBeforePrepare { get; set; } + + public IntPtr Next2IntptrBeforePrepare { get; set; } + + public IntPtr FunctionPointerAfterPrepare { get; set; } + + public IntPtr Next1IntptrAfterPrepare { get; set; } + + public IntPtr Next2IntptrAfterPrepare { get; set; } + + public IntPtr FinalMethodAddress { get; set; } + } +} diff --git a/AsposeHook/Utils.cs b/AsposeHook/Utils.cs new file mode 100644 index 0000000..48df1ff --- /dev/null +++ b/AsposeHook/Utils.cs @@ -0,0 +1,105 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace ExtractResFile.AsposeHook +{ + internal static class Utils + { + private static bool _enableLog; + + public static void EnableLog() + { + _enableLog = true; + } + + public static void DisableLog() + { + _enableLog = false; + } + + public static void LogWrite(string msg) + { + if (_enableLog) + { + Console.Write(msg); + } + } + + public static void LogWriteLine(string msg, ConsoleColor forgroundColor = ConsoleColor.Gray) + { + if (_enableLog) + { + Console.ForegroundColor = forgroundColor; + Console.WriteLine(msg); + Console.ResetColor(); + } + } + + public static string To16String(this IntPtr address) + { + if (Environment.Is64BitProcess) + { + return Convert.ToString(address.ToInt64(), 16).PadLeft(16, '0'); + } + + return Convert.ToString(address.ToInt32(), 16).PadLeft(8, '0'); + } + + public static IntPtr ReadIntPtr(this IntPtr address) + { + return Marshal.ReadIntPtr(address); + } + + public static void ShowMethodInfo(MethodMeta meta) + { + if (_enableLog) + { + Console.WriteLine(); + Console.Write("{0,-19}", "Method:"); + Console.ForegroundColor = ConsoleColor.Yellow; + Console.WriteLine("{0,-15}", meta.Method.Name); + Console.ResetColor(); + Console.Write("{0,-19}", "MethodDesc Addr:"); + Console.WriteLine("{0}", meta.MethodDescAddress.To16String()); + Console.ResetColor(); + Console.Write("{0,-19}", "MethodDesc Value:"); + Console.WriteLine("{0}", meta.MethodDescValue.To16String()); + Console.ResetColor(); + Console.Write("{0,-19}", "GetFunctionPointer:"); + Console.ForegroundColor = ConsoleColor.Yellow; + Console.Write("{0} => ", meta.FunctionPointerBeforePrepare.To16String()); + if (meta.FunctionPointerBeforePrepare != meta.FunctionPointerAfterPrepare) + { + Console.ForegroundColor = ConsoleColor.Green; + } + + Console.WriteLine("{0}", meta.FunctionPointerAfterPrepare.To16String()); + Console.ResetColor(); + Console.Write("{0,-19}", "IntPtr1:"); + Console.ForegroundColor = ConsoleColor.Yellow; + Console.Write("{0} => ", meta.Next1IntptrBeforePrepare.To16String()); + if (meta.Next1IntptrBeforePrepare != meta.Next1IntptrAfterPrepare) + { + Console.ForegroundColor = ConsoleColor.Green; + } + + Console.WriteLine("{0}", meta.Next1IntptrAfterPrepare.To16String()); + Console.ResetColor(); + Console.Write("{0,-19}", "IntPtr2:"); + Console.ForegroundColor = ConsoleColor.Yellow; + Console.Write("{0} => ", meta.Next2IntptrBeforePrepare.To16String()); + if (meta.Next2IntptrBeforePrepare != meta.Next2IntptrAfterPrepare) + { + Console.ForegroundColor = ConsoleColor.Green; + } + + Console.WriteLine("{0}", meta.Next2IntptrAfterPrepare.To16String()); + Console.ResetColor(); + } + } + } +} diff --git a/AsposeWordManage.cs b/AsposeWordManage.cs new file mode 100644 index 0000000..b222b0e --- /dev/null +++ b/AsposeWordManage.cs @@ -0,0 +1,93 @@ +using Aspose.Words; +using Aspose.Words.Fields; +using Aspose.Words.Layout; +using Aspose.Words.Loading; +using Aspose.Words.Tables; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; + +namespace LearnWordManage +{ + public static class AsposeWordManage + { + static AsposeWordManage() + { + ////使用注册码 + //new Aspose.Words.License().SetLicense(new MemoryStream(Convert.FromBase64String( + // "PExpY2Vuc2U+CiAgPERhdGE+CiAgICA8TGljZW5zZWRUbz5TdXpob3UgQXVuYm94IFNvZnR3YXJlIENvLiwgTHRkLjwvTGl" + + // "jZW5zZWRUbz4KICAgIDxFbWFpbFRvPnNhbGVzQGF1bnRlYy5jb208L0VtYWlsVG8+CiAgICA8TGljZW5zZVR5cGU+RGV2ZW" + + // "xvcGVyIE9FTTwvTGljZW5zZVR5cGU+CiAgICA8TGljZW5zZU5vdGU+TGltaXRlZCB0byAxIGRldmVsb3BlciwgdW5saW1pd" + + // "GVkIHBoeXNpY2FsIGxvY2F0aW9uczwvTGljZW5zZU5vdGU+CiAgICA8T3JkZXJJRD4yMDA2MDIwMTI2MzM8L09yZGVySUQ+" + + // "CiAgICA8VXNlcklEPjEzNDk3NjAwNjwvVXNlcklEPgogICAgPE9FTT5UaGlzIGlzIGEgcmVkaXN0cmlidXRhYmxlIGxpY2V" + + // "uc2U8L09FTT4KICAgIDxQcm9kdWN0cz4KICAgICAgPFByb2R1Y3Q+QXNwb3NlLlRvdGFsIGZvciAuTkVUPC9Qcm9kdWN0Pg" + + // "ogICAgPC9Qcm9kdWN0cz4KICAgIDxFZGl0aW9uVHlwZT5FbnRlcnByaXNlPC9FZGl0aW9uVHlwZT4KICAgIDxTZXJpYWxOd" + + // "W1iZXI+OTM2ZTVmZDEtODY2Mi00YWJmLTk1YmQtYzhkYzBmNTNhZmE2PC9TZXJpYWxOdW1iZXI+CiAgICA8U3Vic2NyaXB0" + + // "aW9uRXhwaXJ5PjIwMjEwODI3PC9TdWJzY3JpcHRpb25FeHBpcnk+CiAgICA8TGljZW5zZVZlcnNpb24+My4wPC9MaWNlbnN" + + // "lVmVyc2lvbj4KICAgIDxMaWNlbnNlSW5zdHJ1Y3Rpb25zPmh0dHBzOi8vcHVyY2hhc2UuYXNwb3NlLmNvbS9wb2xpY2llcy" + + // "91c2UtbGljZW5zZTwvTGljZW5zZUluc3RydWN0aW9ucz4KICA8L0RhdGE+CiAgPFNpZ25hdHVyZT5wSkpjQndRdnYxV1NxZ" + + // "1kyOHFJYUFKSysvTFFVWWRrQ2x5THE2RUNLU0xDQ3dMNkEwMkJFTnh5L3JzQ1V3UExXbjV2bTl0TDRQRXE1aFAzY2s0WnhE" + + // "ejFiK1JIWTBuQkh1SEhBY01TL1BSeEJES0NGbWg1QVFZRTlrT0FxSzM5NVBSWmJRSGowOUNGTElVUzBMdnRmVkp5cUhjblJ" + + // "vU3dPQnVqT1oyeDc4WFE9PC9TaWduYXR1cmU+CjwvTGljZW5zZT4="))); + } + + public static byte[] HtmlToPageWord(string htmlBody, string headerName="") + { + //Document doc = new Document(); + //DocumentBuilder builder = new DocumentBuilder(doc); + //var html = $"{htmlBody}";//这是html文本 + //// 替换图片svg为png + //builder.InsertHtml(newHtml); + HtmlLoadOptions loadOptions = new HtmlLoadOptions { ConvertSvgToEmf =false, PreferredControlType = HtmlControlType.StructuredDocumentTag }; + var html =$" {headerName}{htmlBody}"; + using var mStream = new MemoryStream(Encoding.UTF8.GetBytes(html)); + var doc = new Document(mStream, loadOptions); + //设置页眉 + if (!string.IsNullOrEmpty(headerName)) + { + DocumentBuilder builder = new DocumentBuilder(doc); + // 设置页面第一页和其它页显示不同 + doc.FirstSection.PageSetup.DifferentFirstPageHeaderFooter = true; + // 移动到新 Section 的页眉位置开始插入页眉内容。 + builder.MoveToHeaderFooter(HeaderFooterType.HeaderFirst); + builder.MoveToHeaderFooter(HeaderFooterType.HeaderPrimary); + builder.ParagraphFormat.Alignment = ParagraphAlignment.Center; + builder.Font.Name = "宋体"; + builder.Font.Size = 12; + builder.Font.Color = Color.Gray; + builder.Write($"{headerName}"); + + // 设置第一页页码页数 + builder.MoveToHeaderFooter(HeaderFooterType.FooterFirst); + builder.ParagraphFormat.Alignment = ParagraphAlignment.Right; + builder.Font.Name = "宋体"; + builder.Font.Size = 12; + builder.Font.Color = Color.Gray; + builder.InsertField("PAGE", ""); + builder.Write("/"); + builder.InsertField("NUMPAGES", ""); + + // 设置设置第二页页码页数 + builder.MoveToHeaderFooter(HeaderFooterType.FooterPrimary); + builder.ParagraphFormat.Alignment = ParagraphAlignment.Right; + builder.Font.Name = "宋体"; + builder.Font.Size = 12; + builder.Font.Color = Color.Gray; + builder.InsertField("PAGE", ""); + builder.Write("/"); + builder.InsertField("NUMPAGES", ""); + } + using var stream = new MemoryStream(); + doc.Save(stream, SaveFormat.Docx); + return stream.ToArray(); + } + } +} diff --git a/Controllers/PdfController.cs b/Controllers/PdfController.cs new file mode 100644 index 0000000..85206f2 --- /dev/null +++ b/Controllers/PdfController.cs @@ -0,0 +1,50 @@ +using ExtractResFile.AsposeHook; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Net.Http.Headers; +using System.ComponentModel.DataAnnotations; +using System.Text; +using System.Web; + +namespace LearnWordManage.Controllers +{ + [ApiController] + [Route("[controller]")] + public class PdfController : ControllerBase + { + private readonly ILogger _logger; + public PdfController(ILogger logger) + { + _logger = logger; + HookManager.StartHook(); + } + + /// + /// htmlתwordģ + /// + public class HtmlToPagePDFDto + { + [Required] + public string? HtmlBody { get; set; } + public string HeaderName { get; set; } = ""; + } + + ///// + ///// htmlתword + ///// + //[HttpPost, Route("htmltopageword")] + //public FileContentResult HtmlToPageWord(HtmlToPagePDFDto req) + //{ + // if (req.HtmlBody is null) + // throw new Exception("Чת"); + // HttpContext.Response.Headers.AccessControlExposeHeaders = "Content-Disposition"; + // HttpContext.Response.Headers.Add("Content-Disposition", " attachment;filename=" + HttpUtility.UrlEncode(req.HeaderName, Encoding.UTF8).ToUpper() + ".docx"); + // var byteResult = AsposeWordManage.HtmlToPageWord(req.HtmlBody, req.HeaderName); + // var fileName = req.HeaderName+".docx"; + // var mimeType = "application/ms-word"; + // return new FileContentResult(byteResult, mimeType) + // { + // FileDownloadName = fileName + // }; + //} + } +} diff --git a/Controllers/WordController.cs b/Controllers/WordController.cs new file mode 100644 index 0000000..7f6eb1f --- /dev/null +++ b/Controllers/WordController.cs @@ -0,0 +1,62 @@ +using ExtractResFile.AsposeHook; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Net.Http.Headers; +using System.ComponentModel.DataAnnotations; +using System.Text; +using System.Web; + +namespace LearnWordManage.Controllers +{ + [ApiController] + [Route("[controller]")] + public class WordController : ControllerBase + { + + private readonly ILogger _logger; + + public WordController(ILogger logger) + { + _logger = logger; + } + + /// + /// htmlתwordģ + /// + public class HtmlToPageWordDto + { + [Required] + public string? HtmlBody { get; set; } + public string HeaderName { get; set; } = ""; + } + + /// + /// htmlתword + /// + [HttpPost, Route("htmltopageword")] + public FileContentResult HtmlToPageWord(HtmlToPageWordDto req) + { + Console.WriteLine($"htmlתword{DateTime.Now} " +req.HeaderName); + try + { + HookManager.StartHook(); + if (req.HtmlBody is null) + throw new Exception("Чת"); + HttpContext.Response.Headers.AccessControlExposeHeaders = "Content-Disposition"; + HttpContext.Response.Headers.Add("Content-Disposition", " attachment;filename=" + HttpUtility.UrlEncode(req.HeaderName, Encoding.UTF8).ToUpper() + ".docx"); + var byteResult = AsposeWordManage.HtmlToPageWord(req.HtmlBody, req.HeaderName); + var fileName = req.HeaderName + ".docx"; + var mimeType = "application/ms-word"; + return new FileContentResult(byteResult, mimeType) + { + FileDownloadName = fileName + }; + } + catch (Exception ex) + { + Console.WriteLine("htmlתword쳣" + ex.Message); + Console.WriteLine(ex.StackTrace); + throw; + } + } + } +} diff --git a/CustomExceptionFilter.cs b/CustomExceptionFilter.cs new file mode 100644 index 0000000..39f2ffa --- /dev/null +++ b/CustomExceptionFilter.cs @@ -0,0 +1,27 @@ +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Filters; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using System; +using System.Threading.Tasks; + +namespace LearnWordManage +{ + class CustomExceptionFilter : IAsyncExceptionFilter + { + public async Task OnExceptionAsync(ExceptionContext context) + { + var result = new + { + Code = -1, + Message = context.Exception.Message, + StackTrace = context.Exception.StackTrace + }; + context.Result = new JsonResult(result); + Console.WriteLine(context.Exception.Message ); + Console.WriteLine( context.Exception.StackTrace); + context.ExceptionHandled = true; + } + } +} diff --git a/LearnWordManage.csproj b/LearnWordManage.csproj new file mode 100644 index 0000000..446e300 --- /dev/null +++ b/LearnWordManage.csproj @@ -0,0 +1,21 @@ + + + + net6.0 + enable + enable + + + + + + + + + + + Always + + + + diff --git a/LearnWordManage.sln b/LearnWordManage.sln new file mode 100644 index 0000000..05fabaa --- /dev/null +++ b/LearnWordManage.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.8.34330.188 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LearnWordManage", "LearnWordManage.csproj", "{BAC76F58-37E7-4CF0-9183-38119A33ACAA}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {BAC76F58-37E7-4CF0-9183-38119A33ACAA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BAC76F58-37E7-4CF0-9183-38119A33ACAA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BAC76F58-37E7-4CF0-9183-38119A33ACAA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BAC76F58-37E7-4CF0-9183-38119A33ACAA}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {6BB05D13-30F4-445A-829B-9EFBDDB274BF} + EndGlobalSection +EndGlobal diff --git a/Program.cs b/Program.cs new file mode 100644 index 0000000..031a0fc --- /dev/null +++ b/Program.cs @@ -0,0 +1,40 @@ +using LearnWordManage; + +try +{ + var builder = WebApplication.CreateBuilder(args); + + // Add services to the container. + + builder.Services.AddControllers(); + // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle + builder.Services.AddEndpointsApiExplorer(); + builder.Services.AddSwaggerGen(); + builder.Services.AddControllers(options => + { + options.Filters.Add(); + }); + + var app = builder.Build(); + + // Configure the HTTP request pipeline. + if (app.Environment.IsDevelopment()) + { + + } + app.UseSwagger(); + app.UseSwaggerUI(); + + app.UseAuthorization(); + + app.MapControllers(); + + Console.WriteLine("ϵͳ"); + app.Run(); + +} +catch (Exception ex) +{ + Console.WriteLine(ex.Message); + Console.WriteLine(ex.StackTrace); +} \ No newline at end of file diff --git a/Properties/launchSettings.json b/Properties/launchSettings.json new file mode 100644 index 0000000..f1582ac --- /dev/null +++ b/Properties/launchSettings.json @@ -0,0 +1,31 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:37666", + "sslPort": 44355 + } + }, + "profiles": { + "LearnWordManage": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "https://localhost:7099;http://localhost:5021", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/appsettings.Development.json b/appsettings.Development.json new file mode 100644 index 0000000..0c208ae --- /dev/null +++ b/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/appsettings.json b/appsettings.json new file mode 100644 index 0000000..10f68b8 --- /dev/null +++ b/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/runtimeconfig.json b/runtimeconfig.json new file mode 100644 index 0000000..56dbbe2 --- /dev/null +++ b/runtimeconfig.json @@ -0,0 +1,7 @@ +{ + "runtimeOptions": { + "configProperties": { + "System.GC.Concurrent": false + } + } +} \ No newline at end of file