/* * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the License); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using System.IO; using System.Reflection; using System.Runtime.Loader; using System.Linq; using System.Runtime.InteropServices; namespace Tizen.Runtime.Coreclr { public static class AssemblyManager { public static AssemblyLoader CurrentAssemblyLoaderContext { get; private set; } public static bool Launch( [In] string rootPath, [In] string path, [In] int argc, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] [In] string[] argv) { ALog.Debug($"Application Launch path : {path}"); try { DirectoryInfo binDir = new DirectoryInfo(Path.Combine(rootPath, "bin")); DirectoryInfo libDir = new DirectoryInfo(Path.Combine(rootPath, "lib")); if (Directory.Exists(binDir.FullName)) { CurrentAssemblyLoaderContext.AddSearchableDirectory(binDir.FullName); } if (Directory.Exists(libDir.FullName)) { CurrentAssemblyLoaderContext.AddSearchableDirectory(libDir.FullName); } Execute(path, argv); } catch (Exception e) { ALog.Debug("Exception in Launch()"); PrintException(e); return false; } return true; } public static void Prepared() { try { if (!Initialize()) { ALog.Debug($"Failed to Initialized"); } } catch (Exception e) { ALog.Debug("Exception at Preparing"); PrintException(e); } } public static void UnhandledExceptionHandler(object sender, object args) { TypeInfo unhandledExceptionEventArgsType = Type.GetType("UnhandledExceptionEventArgs").GetTypeInfo(); PropertyInfo exception = unhandledExceptionEventArgsType.GetProperty("ExceptionObject"); Exception e = (Exception)exception.GetValue(args); PrintException(e); } public static bool Initialize() { try { /// Set UnhandledException handler with reflection /// we must replace this to no reflection method after AppDomain is comming in used net standard TypeInfo appdomainType = Type.GetType("System.AppDomain").GetTypeInfo(); PropertyInfo currentDomain = appdomainType.GetProperty("CurrentDomain", BindingFlags.Public | BindingFlags.Static); EventInfo unhandledException = appdomainType.GetDeclaredEvent("UnhandledException"); object appDomain = currentDomain.GetValue(null, null); MethodInfo handlerInfo = typeof(AssemblyManager).GetTypeInfo().GetDeclaredMethod("UnhandledExceptionHandler"); Delegate handler = handlerInfo.CreateDelegate(unhandledException.EventHandlerType); var addMethod = unhandledException.GetAddMethod(true); addMethod.Invoke(appDomain, new[] {handler}); } catch (Exception e) { ALog.Debug("Exception on set handler for unhandled exception"); PrintException(e); } try { CurrentAssemblyLoaderContext = new AssemblyLoader(); } catch (Exception e) { ALog.Debug("Exception on Initialized"); PrintException(e); return false; } return true; } public static void Execute(string dllPath, string[] argv) { try { FileInfo f = new FileInfo(dllPath); if (File.Exists(f.FullName)) { Assembly asm = CurrentAssemblyLoaderContext.LoadFromPath(f.FullName); if (asm == null) { throw new FileNotFoundException($"{f.FullName} is not found"); } if (asm.EntryPoint == null) { throw new ArgumentException($"{f.FullName} did not have EntryPoint"); } asm.EntryPoint.Invoke(null, new object[] {argv}); } else { ALog.Debug($"Requested file does not exist: {dllPath}"); } } catch (Exception e) { ALog.Debug("Exception on Execute"); PrintException(e); } } private static void PrintException(Exception exception) { while (exception != null) { ALog.Debug(exception.ToString()); exception = exception.InnerException; } } } }