Modify tizen coding style
[platform/core/dotnet/launcher.git] / 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 AssemblyLoader CurrentAssemblyLoaderContext
29         {
30             get;
31             private set;
32         }
33
34         public static bool Launch(
35                 [In] string rootPath,
36                 [In] string path,
37                 [In] int argc,
38                 [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)]
39                 [In] string[] argv)
40         {
41             ALog.Debug($"Application Launch path : {path}");
42             try
43             {
44                 DirectoryInfo binDir = new DirectoryInfo(Path.Combine(rootPath, "bin"));
45                 DirectoryInfo libDir = new DirectoryInfo(Path.Combine(rootPath, "lib"));
46                 if (Directory.Exists(binDir.FullName))
47                 {
48                     CurrentAssemblyLoaderContext.AddSearchableDirectory(binDir.FullName);
49                 }
50
51                 if (Directory.Exists(libDir.FullName))
52                 {
53                     CurrentAssemblyLoaderContext.AddSearchableDirectory(libDir.FullName);
54                 }
55
56                 Execute(path, argv);
57             }
58             catch (Exception e)
59             {
60                 ALog.Debug("Exception in Launch()");
61                 PrintException(e);
62                 return false;
63             }
64
65             return true;
66         }
67
68         public static void Prepared()
69         {
70             try
71             {
72                 if (!Initialize())
73                 {
74                     ALog.Debug($"Failed to Initialized");
75                 }
76             }
77             catch (Exception e)
78             {
79                 ALog.Debug("Exception at Preparing");
80                 PrintException(e);
81             }
82         }
83
84         public static void UnhandledExceptionHandler(object sender, object args)
85         {
86             TypeInfo unhandledExceptionEventArgsType =
87                 Type.GetType("UnhandledExceptionEventArgs").GetTypeInfo();
88
89             PropertyInfo exception = unhandledExceptionEventArgsType.GetProperty("ExceptionObject");
90             Exception e = (Exception)exception.GetValue(args);
91
92             PrintException(e);
93         }
94
95         public static bool Initialize()
96         {
97             try
98             {
99                 /// Set UnhandledException handler with reflection
100                 /// we must replace this to no reflection method after AppDomain is comming in used net standard
101                 TypeInfo appdomainType = Type.GetType("System.AppDomain").GetTypeInfo();
102                 PropertyInfo currentDomain = appdomainType.GetProperty("CurrentDomain",
103                         BindingFlags.Public | BindingFlags.Static);
104                 EventInfo unhandledException = appdomainType.GetDeclaredEvent("UnhandledException");
105                 object appDomain = currentDomain.GetValue(null, null);
106                 MethodInfo handlerInfo = typeof(AssemblyManager).GetTypeInfo().GetDeclaredMethod("UnhandledExceptionHandler");
107                 Delegate handler = handlerInfo.CreateDelegate(unhandledException.EventHandlerType);
108                 var addMethod = unhandledException.GetAddMethod(true);
109                 addMethod.Invoke(appDomain, new[] {handler});
110             }
111             catch (Exception e)
112             {
113                 ALog.Debug("Exception on set handler for unhandled exception");
114                 PrintException(e);
115             }
116
117             try
118             {
119                 CurrentAssemblyLoaderContext = new AssemblyLoader();
120             }
121             catch (Exception e)
122             {
123                 ALog.Debug("Exception on Initialized");
124                 PrintException(e);
125                 return false;
126             }
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)
141                     {
142                         throw new FileNotFoundException($"{f.FullName} is not found");
143                     }
144
145                     if (asm.EntryPoint == null)
146                     {
147                         throw new ArgumentException($"{f.FullName} did not have EntryPoint");
148                     }
149
150                     asm.EntryPoint.Invoke(null, new object[] {argv});
151                 }
152                 else
153                 {
154                     ALog.Debug($"Requested file does not exist: {dllPath}");
155                 }
156             }
157             catch (Exception e)
158             {
159                 ALog.Debug("Exception on Execute");
160                 PrintException(e);
161             }
162         }
163
164         private static void PrintException(Exception exception)
165         {
166             while (exception != null)
167             {
168                 ALog.Debug(exception.ToString());
169                 exception = exception.InnerException;
170             }
171         }
172
173     }
174 }