zoukankan      html  css  js  c++  java
  • DynamicCallMethodExpressionTreeInvokerHelper CodeDom 动态编译代码 执行代码

    
    namespace Test
    {
        using System;
        using Microsoft.CSharp;
        using System.CodeDom.Compiler;
        using System.Reflection;
        using Microshaoft;
        public class ContextInfo
        {
            public string F1;
        }
        class Program
        {
            static void Main(string[] args)
            {
                string codeSnippet1 = @"
    Console.WriteLine(x);
    Console.WriteLine(y.F1);
    //TResult r;
    return true;
    ";
                string codeSnippet2 = @"
    Console.WriteLine(x);
    Console.WriteLine(y.F1);
    Console.WriteLine(z);
    //TResult r;
    //return true;
    ";
                string codeSnippet3 = @"
    //Console.WriteLine(x);
    //Console.WriteLine(y.F1);
    Console.WriteLine(""Action()"");
    //TResult r;
    //return true;
    ";
                SourceCodeDynamicCompilerInvokers invokers = new SourceCodeDynamicCompilerInvokers();
                invokers
                    .Add
                        (
                            new string[] { "System.dll", @"Noname3.exe" }
                            , new string[] { "System", "System", "Test" }
                            , "Func<string, ContextInfo, bool>"
                            , "Call"
                            , new string[] { "x", "y" }
                            , codeSnippet1
                        );
                invokers
                    .Add
                        (
                            new string[] { "System.dll", "System.dll", @"Noname3.exe" }
                            , new string[] { "System", "System.Text", "Test" }
                            , "Action<int, ContextInfo, bool>"
                            , "Call2"
                            , new string[] { "x", "y", "z" }
                            , codeSnippet2
                        );
                invokers
                    .Add
                        (
                            new string[] { "System.dll", "System.dll", @"Noname3.exe" }
                            , new string[] { "System", "System.Text", "Test" }
                            , "Action"
                            , "Call3"
                            , null //new string[] { "x", "y", "z" }
                            , codeSnippet3
                        );
                invokers.Build();
                //Func<string, ContextInfo, bool> func = (Func<string, ContextInfo, bool>) cr["Call"];
                dynamic func = invokers["Call"];
                var r = func("xxxx", new ContextInfo() { F1 = "FF1" });
                Console.WriteLine(r);
                //Action<int, ContextInfo, bool> action = (Action<int, ContextInfo, bool>) cr["Call2"];
                dynamic action = invokers["Call2"];
                action(999, new ContextInfo() { F1 = "FFF1" }, false);
                //Action action = (Action) cr["Call3"];
                dynamic action2 = invokers["Call3"];
                action2();
                Console.ReadLine();
            }
        }
    }
    namespace Microshaoft
    {
        using System;
        using System.CodeDom.Compiler;
        using System.Collections.Concurrent;
        using System.Linq;
        using System.Reflection;
        using System.Text;
        public class SourceCodeDynamicCompilerInvokers
        {
            private string _codeTemplate = @"
    namespace Microshaoft.Temp
    {{
        {0}
        public static partial class InvokersManager
        {{
            public static
                            {1}                        //方法签名定义,如: Func<string, string, bool>
                            {2}                        //方法名称
                                ()
            {{
                var invoker = new {1}                //方法签名定义,如: Func<string, string, bool>
                                    (
                                        (
                                            {3}        //参数列表
                                        ) =>
                                        {{
                                            {4}        //代码
                                        }}
                                    );
                return invoker;
            }}
        }}
    }}
    ";
            private class CodeTemplatePlaceHolder
            {
                public string[] ReferencedAssemblies;
                public string[] UsingsTargets;
                public string MethodDefinitionStatment;
                public string MethodName;
                public string[] MethodArgs;
                public string EmbedInlineCodeSnippet;
                public Delegate MethodInvoker;
            }
            public Delegate this[string key]
            {
                get
                {
                    return
                        _sourceCodes[key].MethodInvoker;
                }
            }
            private ConcurrentDictionary<string, CodeTemplatePlaceHolder> _sourceCodes
                            = new ConcurrentDictionary<string, CodeTemplatePlaceHolder>();
            private void Compile
                        (
                            string[] referencedAssemblies
                            , string sourceCode
                        )
            {
                CodeDomProvider codeDomProvider = CodeDomProvider.CreateProvider("CSharp");
                var compilerParameters = new CompilerParameters();
                Array
                    .ForEach
                        (
                            referencedAssemblies
                            , (x) =>
                            {
                                compilerParameters
                                    .ReferencedAssemblies
                                    .Add(x);
                            }
                        );
                compilerParameters.GenerateExecutable = false;
                compilerParameters.GenerateInMemory = true;
                //Console.WriteLine(code);
                var compilerResults = codeDomProvider
                                            .CompileAssemblyFromSource
                                                (
                                                    compilerParameters
                                                    , sourceCode
                                                );
                var assembly = compilerResults.CompiledAssembly;
                var codes = _sourceCodes.AsEnumerable();
                var stringBuilder = new StringBuilder();
                foreach (var kvp in codes)
                {
                    MethodInfo mi = assembly
                                        .GetType("Microshaoft.Temp.InvokersManager")
                                        .GetMethod(kvp.Key);
                    Delegate invoker = (Delegate) mi.Invoke(null, null);
                    kvp.Value.MethodInvoker = invoker;
                }
            }
            public void Add
                            (
                                string[] referencedAssemblies
                                , string[] usingsTargets
                                , string methodSignatureDefinition
                                , string methodName
                                , string[] methodArgs
                                , string embedInlineCodeSnippet
                            )
            {
                _sourceCodes
                    .TryAdd
                        (
                                methodName
                                , new CodeTemplatePlaceHolder()
                                    {
                                        ReferencedAssemblies = referencedAssemblies
                                         ,
                                        UsingsTargets = usingsTargets
                                         ,
                                        MethodDefinitionStatment = methodSignatureDefinition
                                         ,
                                        MethodName = methodName
                                         ,
                                        MethodArgs = methodArgs
                                         ,
                                        EmbedInlineCodeSnippet = embedInlineCodeSnippet
                                    }
                        );
            }
            public void Build()
            {
                string[] referencedAssemblies
                            = _sourceCodes
                                .SelectMany
                                    (
                                        (x) =>
                                        {
                                            return
                                                x
                                                    .Value
                                                    .ReferencedAssemblies;
                                        }
                                    ).Distinct()
                                     .ToArray();
                var sourceCodes = _sourceCodes.AsEnumerable();
                var stringBuilder = new StringBuilder();
                foreach (var kvp in sourceCodes)
                {
                    var usingStatement = "using {0};";
                    var usingsTargets = kvp
                                            .Value
                                            .UsingsTargets
                                            .Distinct();
                    var usingsStatementsItems
                                = usingsTargets
                                    .Select
                                        (
                                            (xx) =>
                                            {
                                                var rr = string.Format(usingStatement, xx);
                                                return rr;
                                            }
                                        );
                    var usingsStatements = string.Join("\r\n", usingsStatementsItems);
                    var methodArgs = kvp
                                        .Value
                                        .MethodArgs;
                    var methodArgsStatement = string.Empty;
                    if
                        (
                            methodArgs != null
                            &&
                            methodArgs.Length > 0
                        )
                    {
                        methodArgsStatement = string.Join(", ", methodArgs);
                    }
                    var sourceCode = string
                                        .Format
                                            (
                                                _codeTemplate
                                                , usingsStatements
                                                , kvp.Value.MethodDefinitionStatment
                                                , kvp.Value.MethodName
                                                , methodArgsStatement
                                                , kvp.Value.EmbedInlineCodeSnippet
                                            );
                    stringBuilder
                        .AppendLine(sourceCode);
                }
                Compile(referencedAssemblies, stringBuilder.ToString());
            }
        }
    }
    
    
    
    namespace ConsoleApplication
    {
        using System;
        using System.Collections.Generic;
        using System.IO;
        using System.Net.Mail;
        using System.Net.Mime;
        using Microshaoft;
        public class Class1
        {
            static void Main(string[] args)
            {
                Console.WriteLine("生成 eml 文件");
                string html = "<html><body><a href=\"http://www.live.com\"><img src=\"cid:attachment1\"></a>";
                html += "<script src=\"cid:attachment2\"></script>中国字";
                html += "<a href=\"http://www.google.com\"><br><img src=\"cid:attachment1\"></a><script>alert('mail body xss')<script></body></html>";
                AlternateView view = AlternateView.CreateAlternateViewFromString(html, null, MediaTypeNames.Text.Html);
                //LinkedResource picture = new LinkedResource(@"pic.JPG", MediaTypeNames.Image.Jpeg);
                //picture.ContentId = "attachment1";
                //view.LinkedResources.Add(picture);
                //LinkedResource script = new LinkedResource(@"a.js", MediaTypeNames.Text.Plain);
                //script.ContentId = "attachment2";
                //view.LinkedResources.Add(script);
                MailMessage mail = new MailMessage();
                mail.AlternateViews.Add(view);
                mail.From = new MailAddress("test@microshaoft.com", "<script>alert('mail from xss')</script>");
                mail.To.Add(new MailAddress("microshaoft@gmail.com", "<script>alert('mail to xss')</script>"));
                mail.To.Add(new MailAddress("microshaoft@qq.com", "<script>alert('mail to xss')</script>"));
                mail.Subject = "<script>alert('mail subject xss')</script>" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                byte[] buffer = mail.GetBytes();
                File.WriteAllBytes(@"d:\temp.eml", buffer);
                Console.WriteLine("====================================================================");
                Console.ReadLine();
                Console.WriteLine("计算表达式");
                string formula = "(({0}-{1})/{2}+{3})*{4}";
                string result = JScriptEvaluator.ComputeFormula<double>
                                                        (
                                                            formula
                                                            , 1f
                                                            , 2.1
                                                            , 3.1
                                                            , 4.0
                                                            , 5.0
                                                        );
                Console.WriteLine(result);
                double x;
                x = DataTableColumnExpression.ComputeFormula<double, double>
                                                        (
                                                            formula
                                                            , 1f
                                                            , 2.1
                                                            , 3.1
                                                            , 4.0
                                                            , 5.0
                                                        );
                Console.WriteLine(x);
                //=================================================================================================
                formula = "IIF(1=2, F1, F2) + ((--F1) * F2) + F3";
                var tuples = new Tuple<string, double>[]
                                                {
                                                    Tuple.Create<string,double>("F1", 1.0)
                                                    , Tuple.Create<string,double>("F2", 2.0)
                                                    , Tuple.Create<string,double>("F3", 3.0)
                                                    , Tuple.Create<string,double>("F4", 4.0)
                                                    , Tuple.Create<string,double>("F3", 2.0)
                                                };
                x = DataTableColumnExpression.ComputeFormula<double, double>(formula, tuples);
                Console.WriteLine(x);
                Console.ReadLine();
            }
        }
    }
    namespace Microshaoft
    {
        using System;
        using System.CodeDom.Compiler;
        using System.Collections.Generic;
        using System.Data;
        using System.Linq;
        using System.Reflection;
        public class DataTableColumnExpression
        {
            private static MethodInfo _mi = typeof(string).GetMethods().First
                                                                        (
                                                                            m => m.Name.Equals("Format")
                                                                            && m.GetParameters().Length == 2
                                                                            && m.IsStatic
                                                                            && m.GetParameters()[1].Name == "args"
                                                                        );
            private class ObjectEqualityComparer<T> : IEqualityComparer<T>
            {
                private Func<T, T, bool> _onEqualsProcessFunc;
                private Func<T, int> _onGetHashCodeProcessFunc;
                public ObjectEqualityComparer
                            (
                                Func<T, T, bool> onEqualsProcessFunc
                                , Func<T, int> onGetHashCodeProcessFunc
                            )
                {
                    _onEqualsProcessFunc = onEqualsProcessFunc;
                    _onGetHashCodeProcessFunc = onGetHashCodeProcessFunc;
                }
                public bool Equals(T x, T y)
                {
                    if (Object.ReferenceEquals(x, y))
                    {
                        return true;
                    }
                    if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
                    {
                        return false;
                    }
                    return _onEqualsProcessFunc(x, y);
                }
                public int GetHashCode(T x)
                {
                    if (Object.ReferenceEquals(x, null))
                    {
                        return 0;
                    }
                    return _onGetHashCodeProcessFunc(x);
                }
            }
            public static TResult ComputeFormula<TResult, TParameter>
                                                        (
                                                            string formula
                                                            , params TParameter[] parameters
                                                        )
            {
                var dt = new DataTable();
                var list = parameters.ToList();
                var parametersNames = new List<string>(); ;
                int i = 0;
                Array.ForEach
                        (
                            parameters
                            , (x) =>
                            {
                                string f = string.Format("F{0}", i++);
                                parametersNames.Add(f);
                                var dc = new DataColumn(f, typeof(TParameter));
                                dt.Columns.Add(dc);
                            }
                        );
                string expression = string.Format(formula, parametersNames.ToArray());
                dt.Columns.Add(new DataColumn("Microshaoft", typeof(TResult), expression));
                var dr = dt.NewRow();
                i = 0;
                Array.ForEach
                (
                    parameters
                    , (x) =>
                    {
                        dr[i++] = x;
                    }
                );
                dt.Rows.Add(dr);
                return (TResult)dr["Microshaoft"];
            }
            public static TResult ComputeFormula<TResult, TParameter>
                                                        (
                                                            string formula
                                                            , params Tuple<string, TParameter>[] parameters
                                                        )
            {
                var dt = new DataTable();
                var comparer = new ObjectEqualityComparer<Tuple<string, TParameter>>
                                                (
                                                    (x, y) =>
                                                    {
                                                        return x.Item1 == y.Item1;
                                                    }
                                                    , (x) =>
                                                    {
                                                        return x.Item1.GetHashCode();
                                                    }
                                                );
                var list = parameters.Distinct
                                        (
                                            comparer
                                        )
                                        .ToList();
                list.ForEach
                        (
                            (x) =>
                            {
                                var dc = new DataColumn
                                                (
                                                    x.Item1
                                                    , x.Item2.GetType()
                                                );
                                dt.Columns.Add(dc);
                            }
                        );
                dt.Columns.Add(new DataColumn("Microshaoft", typeof(TResult), formula));
                var dr = dt.NewRow();
                list.ForEach
                        (
                            (x) =>
                            {
                                dr[x.Item1] = x.Item2;
                            }
                        );
                dt.Rows.Add(dr);
                return (TResult)dr["Microshaoft"];
            }
        }
        public class JScriptEvaluator
        {
            private static MethodInfo _mi = typeof(string).GetMethods().First
                                                                            (
                                                                                m => m.Name.Equals("Format")
                                                                                && m.GetParameters().Length == 2
                                                                                && m.IsStatic
                                                                                && m.GetParameters()[1].Name == "args"
                                                                            );
            private static Func<string, object[], object> _func = null;
            public static string ComputeFormula<TParameter>(string formula, params TParameter[] parameters)
            {
                object[] objects = new object[parameters.Length];
                Array.Copy(parameters, objects, objects.Length);
                string expression1 = string.Format(formula, objects);
                return (string)JScriptEvaluator.Eval(expression1);
                //=====================================================================
                object[] ps = new object[parameters.Length];
                Array.Copy(parameters, 0, ps, 0, ps.Length);
                if (_func == null)
                {
                    _func = DynamicCallMethodExpressionTreeInvokerHelper.CreateMethodCallInvokerFunc<string, string>
                                                    (
                                                        typeof(string)
                                                        , () =>
                                                        {
                                                            var methodsInfos = typeof(string).GetMethods();
                                                            var methodInfo = methodsInfos.First
                                                                                            (
                                                                                                (x) =>
                                                                                                {
                                                                                                    var parametersInfos = x.GetParameters();
                                                                                                    //Debug.Assert(x.Name.ToLower() == "Format".ToLower());
                                                                                                    return
                                                                                                        x.Name.ToLower() == "Format".ToLower()
                                                                                                        && x.IsStatic
                                                                                                        && parametersInfos[0].ParameterType == typeof(string)
                                                                                                        && parametersInfos[1].ParameterType == typeof(object[])
                                                                                                        && Attribute.IsDefined
                                                                                                                        (
                                                                                                                            parametersInfos[1]
                                                                                                                            , typeof(ParamArrayAttribute)
                                                                                                                        );
                                                                                                }
                                                                                            );
                                                            return methodInfo;
                                                        }
                                                    );
                }
                string expression = (string)_mi.Invoke
                                                    (
                                                        null
                                                        , new object[]
                                                                {
                                                                    formula
                                                                    , ps
                                                                }
                                                    );
                expression = (string) _func
                                        (
                                            formula
                                            , new object[]
                                                        {
                                                            formula
                                                            , ps
                                                        }
                                        );
                return (string) JScriptEvaluator.Eval(expression);
            }
            public static object Eval(string statement)
            {
                return _evaluatorType.InvokeMember
                                            (
                                                "Eval"
                                                , BindingFlags.InvokeMethod
                                                , null
                                                , _evaluator
                                                , new object[]
                                                        {
                                                            statement
                                                        }
                                            );
            }
            static JScriptEvaluator()
            {
                CodeDomProvider provider = CodeDomProvider.CreateProvider("JScript");
                CompilerParameters parameters;
                parameters = new CompilerParameters();
                parameters.GenerateInMemory = true;
                CompilerResults results;
                results = provider.CompileAssemblyFromSource(parameters, _JScript);
                Assembly assembly = results.CompiledAssembly;
                _evaluatorType = assembly.GetType("Microshaoft.JScriptEvaluator");
                var constructorInfo = _evaluatorType.GetConstructors().First();
                var func = DynamicCallMethodExpressionTreeInvokerHelper.CreateNewInstanceConstructorInvokerFunc
                                                                (
                                                                    _evaluatorType
                                                                    , constructorInfo
                                                                );
                _evaluator = func(null);
                //_evaluator = Activator.CreateInstance(_evaluatorType);
            }
            private static object _evaluator = null;
            private static Type _evaluatorType = null;
            /// <summary>
            /// JScript代码
            /// </summary>
            private static readonly string _JScript =
                @"
                    package Microshaoft
                    {
                        class JScriptEvaluator
                        {
                            public function Eval(statement : String) : String
                            {
                                return eval(statement);
                            }
                        }
                    }
                ";
        }
    }
    namespace Microshaoft
    {
        using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Linq.Expressions;
        using System.Reflection;
        public static class DynamicCallMethodExpressionTreeInvokerHelper
        {
            public static Func<object[], object> CreateNewInstanceConstructorInvokerFunc
                                                            (
                                                                Type type
                                                                , Func<ConstructorInfo> getConstructorInfoFunc
                                                            )
            {
                var constructorInfo = getConstructorInfoFunc();
                return CreateNewInstanceConstructorInvokerFunc<object>
                                                            (
                                                                type
                                                                , constructorInfo
                                                            );
            }
            public static Func<object[], T> CreateNewInstanceConstructorInvokerFunc<T>
                                                            (
                                                                Type type
                                                                , Func<ConstructorInfo> getConstructorInfoFunc
                                                            )
            {
                var constructorInfo = getConstructorInfoFunc();
                return CreateNewInstanceConstructorInvokerFunc<T>
                                                            (
                                                                type
                                                                , constructorInfo
                                                            );
            }
            public static Func<object[], object> CreateNewInstanceConstructorInvokerFunc
                                                            (
                                                                Type type
                                                                , ConstructorInfo constructorInfo
                                                            )
            {
                return CreateNewInstanceConstructorInvokerFunc<object>(type, constructorInfo);
            }
            public static Func<object[], T> CreateNewInstanceConstructorInvokerFunc<T>
                                                            (
                                                                Type type
                                                                , ConstructorInfo constructorInfo
                                                            )
            {
                var parametersInfos = constructorInfo.GetParameters();
                var constructorParametersExpressions = new List<ParameterExpression>();
                int i = 0;
                Array.ForEach
                        (
                            parametersInfos
                            , (x) =>
                            {
                                var parameterExpression = Expression.Parameter
                                                                        (
                                                                            x.ParameterType
                                                                            , "p" + i.ToString()
                                                                        );
                                constructorParametersExpressions.Add(parameterExpression);
                                i++;
                            }
                        );
                var newExpression = Expression.New(constructorInfo, constructorParametersExpressions);
                var inner = Expression.Lambda(newExpression, constructorParametersExpressions);
                var args = Expression.Parameter(typeof(object[]), "args");
                var body = Expression.Invoke
                                        (
                                            inner
                                            , constructorParametersExpressions.Select
                                                                        (
                                                                            (p, ii) =>
                                                                            {
                                                                                return Expression.Convert
                                                                                                (
                                                                                                    Expression.ArrayIndex
                                                                                                                    (
                                                                                                                        args
                                                                                                                        , Expression.Constant(ii)
                                                                                                                    )
                                                                                                    , p.Type
                                                                                                );
                                                                            }
                                                                        ).ToArray()
                                        );
                var outer = Expression.Lambda<Func<object[], T>>(body, args);
                var func = outer.Compile();
                return func;
            }
            public static Action<T, object[]> CreateMethodCallInvokerAction<T>
                                                                (
                                                                    Type type
                                                                    , Func<MethodInfo> getMethodInfoFunc
                                                                )
            {
                var methodInfo = getMethodInfoFunc();
                return CreateMethodCallInvokerAction<T>
                                                    (
                                                        type
                                                        , methodInfo
                                                    );
            }
            public static Action<T, object[]> CreateMethodCallInvokerAction<T>
                                                                (
                                                                    Type type
                                                                    , MethodInfo methodInfo
                                                                )
            {
                ParameterExpression instanceParameterExpression;
                MethodCallExpression methodCallExpression;
                ParameterExpression argumentsParameterExpression = GetMethodArgumentsParameterExpression
                                        (
                                            type
                                            , methodInfo
                                            , out instanceParameterExpression
                                            , out methodCallExpression
                                        );
                var lambda = Expression.Lambda<Action<T, object[]>>(methodCallExpression, instanceParameterExpression, argumentsParameterExpression);
                var action = lambda.Compile();
                return action;
            }
            public static Func<T, object[], TResult> CreateMethodCallInvokerFunc<T, TResult>
                                                                (
                                                                    Type type
                                                                    , Func<MethodInfo> getMethodInfoFunc
                                                                )
            {
                var methodInfo = getMethodInfoFunc();
                return
                    CreateMethodCallInvokerFunc<T, TResult>
                                                        (
                                                            type
                                                            , methodInfo
                                                        );
            }
            public static Func<T, object[], TResult> CreateMethodCallInvokerFunc<T, TResult>
                                                                (
                                                                    Type type
                                                                    , MethodInfo methodInfo
                                                                )
            {
                ParameterExpression instanceParameterExpression;
                MethodCallExpression methodCallExpression;
                ParameterExpression argumentsParameterExpression = GetMethodArgumentsParameterExpression
                                        (
                                            type
                                            , methodInfo
                                            , out instanceParameterExpression
                                            , out methodCallExpression
                                        );
                var lambda = Expression.Lambda<Func<T, object[], TResult>>(methodCallExpression, instanceParameterExpression, argumentsParameterExpression);
                var func = lambda.Compile();
                return func;
            }
            private static ParameterExpression GetMethodArgumentsParameterExpression
                                                (
                                                    Type type
                                                    , MethodInfo methodInfo
                                                    , out ParameterExpression instanceParameterExpression
                                                    , out MethodCallExpression methodCallExpression
                                                )
            {
                var argumentsParameterExpression = Expression.Parameter(typeof(object[]), "args");
                instanceParameterExpression = Expression.Parameter(type);
                UnaryExpression instanceConvertUnaryExpression = null;
                if (!methodInfo.IsStatic)
                {
                    instanceConvertUnaryExpression = Expression.Convert(instanceParameterExpression, type);
                }
                var parametersParameterExpressionList = new List<Expression>();
                int i = 0;
                var parametersInfos = methodInfo.GetParameters();
                Array.ForEach
                        (
                            parametersInfos
                            , (x) =>
                            {
                                BinaryExpression valueObject = Expression.ArrayIndex
                                                                            (
                                                                                argumentsParameterExpression
                                                                                , Expression.Constant(i)
                                                                            );
                                UnaryExpression valueCast = Expression.Convert
                                                                            (
                                                                                valueObject
                                                                                , x.ParameterType
                                                                            );
                                parametersParameterExpressionList.Add(valueCast);
                                i++;
                            }
                        );
                methodCallExpression = Expression.Call(instanceConvertUnaryExpression, methodInfo, parametersParameterExpressionList);
                return argumentsParameterExpression;
            }
        }
    }
    namespace Microshaoft
    {
        using System;
        using System.IO;
        using System.Net.Mail;
        using System.Reflection;
        public static partial class ExtensionMethodsManager
        {
            public static byte[] GetBytes(this MailMessage mailMessage)
            {
                Assembly assembly = typeof(SmtpClient).Assembly;
                Type type = assembly.GetType("System.Net.Mail.MailWriter");
                var parametersTypes = new[]
                                        { 
                                            typeof(Stream)
                                        };
                object x = null;
                using (Stream stream = new MemoryStream())
                {
                    var constructorInfo = type.GetConstructor
                                                        (
                                                            BindingFlags.Instance | BindingFlags.NonPublic
                                                            , null
                                                            , parametersTypes
                                                            , null
                                                        );
                    var func = DynamicCallMethodExpressionTreeInvokerHelper.CreateNewInstanceConstructorInvokerFunc<object>
                                                            (
                                                                type
                                                                , constructorInfo
                                                            );
                    x = func(new[] { stream });
                    var action = DynamicCallMethodExpressionTreeInvokerHelper.CreateMethodCallInvokerAction<MailMessage>
                                                            (
                                                                typeof(MailMessage)
                                                                , () =>
                                                                {
                                                                    var methodInfo = typeof(MailMessage).GetMethod
                                                                                            (
                                                                                                "Send"
                                                                                                , BindingFlags.NonPublic | BindingFlags.Instance
                                                                                                , null
                                                                                                , new[] { type, typeof(bool) }
                                                                                                , null
                                                                                            );
                                                                    return methodInfo;
                                                                }
                                                            );
                    action
                        (
                            mailMessage
                            , new[]
                                {
                                    x
                                    , true
                                }
                        );
                    byte[] buffer = StreamDataHelper.ReadDataToBytes(stream);
                    return buffer;
                }
            }
        }
    }
    namespace Microshaoft
    {
        using System.IO;
        public static class StreamDataHelper
        {
            public static byte[] ReadDataToBytes(Stream stream)
            {
                byte[] buffer = new byte[64 * 1024];
                MemoryStream ms = new MemoryStream();
                int r = 0;
                int l = 0;
                long position = -1;
                if (stream.CanSeek)
                {
                    position = stream.Position;
                    stream.Position = 0;
                }
                while (true)
                {
                    r = stream.Read(buffer, 0, buffer.Length);
                    if (r > 0)
                    {
                        l += r;
                        ms.Write(buffer, 0, r);
                    }
                    else
                    {
                        break;
                    }
                }
                byte[] bytes = new byte[l];
                ms.Position = 0;
                ms.Read(bytes, 0, (int)l);
                ms.Close();
                ms.Dispose();
                ms = null;
                if (position >= 0)
                {
                    stream.Position = position;
                }
                return bytes;
            }
        }
    }
    
    
  • 相关阅读:
    [Python] Python2 、Python3 urllib 模块对应关系
    [Python] Mac pip安装的模块包路径以及常规python路径
    git 使用详解
    版本控制工具简介
    python基础练习题(二)
    python简介,安装
    python基础练习题(一)
    python练习题之面向对象(三)
    python之input函数,if,else条件语句使用的练习题(一)
    C++ 静态变量
  • 原文地址:https://www.cnblogs.com/Microshaoft/p/2635636.html
Copyright © 2011-2022 走看看