Basename bug fixed
[platform/core/dotnet/launcher.git] / Tizen.Runtime / Tizen.Runtime.Coreclr / AssemblyManager.cs
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 using System;
18 using System.IO;
19 using System.Reflection;
20 using System.Runtime.Loader;
21 using System.Linq;
22 using System.Runtime.InteropServices;
23
24 namespace Tizen.Runtime.Coreclr
25 {
26     public static class AssemblyManager
27     {
28         public static bool Launch(
29                 [In] string rootPath,
30                 [In] string path,
31                 [In] int argc,
32                 [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=2)]
33                 [In] string[] argv)
34         {
35             ALog.Debug($"Application Launch path : {path}");
36             try
37             {
38                 DirectoryInfo bindir = new DirectoryInfo(Path.Combine(rootPath, "bin"));
39                 DirectoryInfo libdir = new DirectoryInfo(Path.Combine(rootPath, "lib"));
40                 if (Directory.Exists(bindir.FullName))
41                 {
42                     CurrentAssemblyLoaderContext.AddSearchableDirectory(bindir.FullName);
43                 }
44                 if (Directory.Exists(libdir.FullName))
45                 {
46                     CurrentAssemblyLoaderContext.AddSearchableDirectory(libdir.FullName);
47                 }
48                 Execute(path, argv);
49             }
50             catch(Exception e)
51             {
52                 ALog.Debug("Exception in Launch()");
53                 PrintException(e);
54                 return false;
55             }
56
57             return true;
58         }
59
60         public static void Prepared()
61         {
62             try
63             {
64                 if (!Initialize())
65                 {
66                     ALog.Debug($"Failed to Initialized");
67                 }
68             }
69             catch(Exception e)
70             {
71                 ALog.Debug("Exception at Preparing");
72                 PrintException(e);
73             }
74         }
75
76         private static void PrintException(Exception exception)
77         {
78             while (exception != null)
79             {
80                 ALog.Debug(exception.ToString());
81                 exception = exception.InnerException;
82             }
83         }
84
85         public static void UnhandledExceptionHandler(object sender, object args)
86         {
87             TypeInfo unhandledExceptionEventArgsType =
88                 Type.GetType("UnhandledExceptionEventArgs").GetTypeInfo();
89
90             PropertyInfo exception = unhandledExceptionEventArgsType.GetProperty("ExceptionObject");
91             Exception e = (Exception)exception.GetValue(args);
92
93             PrintException(e);
94         }
95
96         public static bool Initialize()
97         {
98             try
99             {
100                 // Set UnhandledException handler with reflection
101                 // we must replace this to no reflection method after AppDomain is comming in used net standard
102                 TypeInfo appdomainType = Type.GetType("System.AppDomain").GetTypeInfo();
103                 PropertyInfo currentDomain = appdomainType.GetProperty("CurrentDomain",
104                         BindingFlags.Public | BindingFlags.Static);
105                 EventInfo unhandledException = appdomainType.GetDeclaredEvent("UnhandledException");
106                 object appdomain = currentDomain.GetValue(null, null);
107                 MethodInfo handlerInfo = typeof(AssemblyManager).GetTypeInfo().GetDeclaredMethod("UnhandledExceptionHandler");
108                 Delegate handler = handlerInfo.CreateDelegate(unhandledException.EventHandlerType);
109                 var addMethod = unhandledException.GetAddMethod(true);
110                 addMethod.Invoke(appdomain, new[] {handler});
111             }
112             catch (Exception e)
113             {
114                 ALog.Debug("Exception on set handler for unhandled exception");
115                 PrintException(e);
116             }
117
118             try
119             {
120                 CurrentAssemblyLoaderContext = new AssemblyLoader();
121             }
122             catch (Exception e)
123             {
124                 ALog.Debug("Exception on Initialized");
125                 PrintException(e);
126                 return false;
127             }
128             return true;
129         }
130
131         public static void Execute(string dllPath, string[] argv)
132         {
133             try
134             {
135                 FileInfo f = new FileInfo(dllPath);
136                 if (File.Exists(f.FullName))
137                 {
138                     Assembly asm = CurrentAssemblyLoaderContext.LoadFromPath(f.FullName);
139
140                     if (asm == null) throw new FileNotFoundException($"{f.FullName} is not found");
141                     if (asm.EntryPoint == null) throw new ArgumentException($"{f.FullName} did not have EntryPoint");
142                     asm.EntryPoint.Invoke(null, new object[]{argv});
143                 }
144                 else
145                 {
146                     ALog.Debug($"Requested file does not exist: {dllPath}");
147                 }
148             }
149             catch (Exception e)
150             {
151                 ALog.Debug("Exception on Execute");
152                 PrintException(e);
153             }
154         }
155
156         public static AssemblyLoader CurrentAssemblyLoaderContext
157         {
158             get;
159             private set;
160         }
161
162     }
163 }