private DynamicScriptExecuteResult <T> ExecuteUntrustedCode <T>(Type type, MethodInfo methodInfo, int millisecondsTimeout, params object[] parameters) { string errorMessage = string.Format("[Assembly:{0},Method:{1},Timeout:{2}, execution timed out.", type.Assembly.FullName, methodInfo.Name, millisecondsTimeout); DynamicScriptExecuteResult <T> result = DynamicScriptExecuteResult <T> .Error(errorMessage); var tokenSource = new CancellationTokenSource(); var token = tokenSource.Token; var t = Task.Factory.StartNew(() => { result = ExecuteTrustedCode <T>(type, methodInfo, parameters); }, token); if (!t.Wait(millisecondsTimeout, token)) { tokenSource.Cancel(); _logger.LogError(errorMessage); return(DynamicScriptExecuteResult <T> .Error("execution timed out!")); } return(result); //这里用不同的应用程序域重构,增强沙箱支持 //Note:.NET Core 3.0 Preview 5 start support //暂时不支持沙箱环境 //if (SettingsConfig.Instance.SandboxEnable) //{ // object obj = null; // var sandBoxer = new SandBoxer(); // obj = sandBoxer.ExecuteUntrustedCode(type, functionName, 0, parameters); // sandBoxer.UnloadSandBoxer(); // return (T)obj; //} }
private DynamicScriptExecuteResult <T> CallFunction <T>(DynamicScript dynamicScript) { if (dynamicScript.FunctionName.IsNullOrEmpty()) { return(DynamicScriptExecuteResult <T> .Error($"function name can not be null.")); } if (_scriptHash.IsNullOrEmpty() || !_scriptTypeDict.ContainsKey(_scriptHash)) { return(DynamicScriptExecuteResult <T> .Error($"type not found.")); } var type = _scriptTypeDict[_scriptHash]; var methodInfo = type.Method(dynamicScript.FunctionName); if (methodInfo == null) { return(DynamicScriptExecuteResult <T> .Error($"function name can not be null.")); } if (dynamicScript.IsTrustedScript) { return(ExecuteTrustedCode <T>(type, methodInfo, dynamicScript.Parameters)); } else { if (dynamicScript.MillisecondsTimeout <= 0) { return(DynamicScriptExecuteResult <T> .Error("if execute untrusted code,please setting the milliseconds timeout!")); } return(ExecuteUntrustedCode <T>(type, methodInfo, dynamicScript.MillisecondsTimeout, dynamicScript.Parameters)); } }
private DynamicScriptExecuteResult <T> ExecuteTrustedCode <T>(Type type, MethodInfo methodInfo, params object[] parameters) { object result = null; var parms = methodInfo.GetParameters(); var safeParameters = SafeTypeConvertParameters(methodInfo.Name, parms, parameters); if (methodInfo.IsStatic) { result = type.TryCallMethod(methodInfo.Name, true, parms.Select(t => t.Name).ToArray(), parms.Select(t => t.ParameterType).ToArray(), safeParameters); } else { result = Activator.CreateInstance(type).TryCallMethod(methodInfo.Name, true, parms.Select(t => t.Name).ToArray(), parms.Select(t => t.ParameterType).ToArray(), safeParameters); } return(DynamicScriptExecuteResult <T> .Success(data : (T)result)); }
private DynamicScriptExecuteResult <T> RunningDynamicScript <T>(DynamicScript dynamicScript) { //检查编译 if (!BuildDynamicScript(dynamicScript, out string errorMessage)) { _logger.LogError($"Build Script Error ! Script Info:{JsonConvert.SerializeObject(dynamicScript)}"); return(DynamicScriptExecuteResult <T> .Error(errorMessage)); } try { //是否开启执行分析,统计非常耗时且会带来更多GC开销,正常运行过程请关闭! if (dynamicScript.IsExecutionStatistics) { Stopwatch stopwatch = new Stopwatch(); //程序执行时间 var startMemory = GC.GetTotalMemory(true); //方法调用内存占用 stopwatch.Start(); var result = CallFunction <T>(dynamicScript); stopwatch.Stop(); result.TotalMemoryAllocated = GC.GetTotalMemory(true) - startMemory; result.ProcessorTime = stopwatch.ElapsedMilliseconds; return(result); } return(CallFunction <T>(dynamicScript)); } catch (MissingMethodException missingMethod) { _logger.LogError(missingMethod, string.Format("TenantId:{0},FunctionName:{1},Language:{2},AppName:{3},ScriptHash:{4},ParameterCount:{5},ErrorMsg: {6}", _tenantId, dynamicScript.FunctionName, "CSharp", _currentAppName, _scriptHash, dynamicScript.Parameters?.Length, missingMethod.Message)); return(DynamicScriptExecuteResult <T> .Error($"function name can not be null.")); } catch (Exception ex) { _logger.LogError(ex, string.Format("Script objectId:{0},tenantId:{1},appName:{2},functionName:{3},errorMsg:{4}", null, dynamicScript.TenantId, _currentAppName, dynamicScript.FunctionName, ex.Message)); return(DynamicScriptExecuteResult <T> .Error(ex.Message + ",innerEx:" + ex.InnerException?.Message)); } }
public DynamicScriptExecuteResult CheckScript(DynamicScript dynamicScript) { ArgumentsCheck(dynamicScript); PreProcessing(dynamicScript); return(BuildDynamicScript(dynamicScript, out string errorMsg) ? DynamicScriptExecuteResult.Success() : DynamicScriptExecuteResult.Error(errorMsg)); }