AppDomain.cs 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436
  1. // Licensed to the .NET Foundation under one or more agreements.
  2. // The .NET Foundation licenses this file to you under the MIT license.
  3. // See the LICENSE file in the project root for more information.
  4. #pragma warning disable CS0067 // events are declared but not used
  5. using System.Diagnostics;
  6. using System.IO;
  7. using System.Reflection;
  8. using System.Runtime.ExceptionServices;
  9. using System.Runtime.Loader;
  10. using System.Runtime.Remoting;
  11. using System.Security;
  12. using System.Security.Permissions;
  13. using System.Security.Principal;
  14. using System.Threading;
  15. namespace System
  16. {
  17. #if PROJECTN
  18. [Internal.Runtime.CompilerServices.RelocatedType("System.Runtime.Extensions")]
  19. #endif
  20. public sealed partial class AppDomain : MarshalByRefObject
  21. {
  22. private static readonly AppDomain s_domain = new AppDomain();
  23. private readonly object _forLock = new object();
  24. private IPrincipal? _defaultPrincipal;
  25. private PrincipalPolicy _principalPolicy = PrincipalPolicy.NoPrincipal;
  26. private Func<IPrincipal>? s_getWindowsPrincipal;
  27. private Func<IPrincipal>? s_getUnauthenticatedPrincipal;
  28. private AppDomain() { }
  29. public static AppDomain CurrentDomain => s_domain;
  30. public string? BaseDirectory => AppContext.BaseDirectory;
  31. public string? RelativeSearchPath => null;
  32. public AppDomainSetup SetupInformation => new AppDomainSetup();
  33. public PermissionSet PermissionSet => new PermissionSet(PermissionState.Unrestricted);
  34. public event UnhandledExceptionEventHandler? UnhandledException
  35. {
  36. add { AppContext.UnhandledException += value; }
  37. remove { AppContext.UnhandledException -= value; }
  38. }
  39. public string? DynamicDirectory => null;
  40. [ObsoleteAttribute("AppDomain.SetDynamicBase has been deprecated. Please investigate the use of AppDomainSetup.DynamicBase instead. https://go.microsoft.com/fwlink/?linkid=14202")]
  41. public void SetDynamicBase(string? path) { }
  42. public string FriendlyName
  43. {
  44. get
  45. {
  46. Assembly? assembly = Assembly.GetEntryAssembly();
  47. return assembly != null ? assembly.GetName().Name! : "DefaultDomain";
  48. }
  49. }
  50. public int Id => 1;
  51. public bool IsFullyTrusted => true;
  52. public bool IsHomogenous => true;
  53. public event EventHandler? DomainUnload;
  54. public event EventHandler<FirstChanceExceptionEventArgs>? FirstChanceException
  55. {
  56. add { AppContext.FirstChanceException += value; }
  57. remove { AppContext.FirstChanceException -= value; }
  58. }
  59. public event EventHandler? ProcessExit
  60. {
  61. add { AppContext.ProcessExit += value; }
  62. remove { AppContext.ProcessExit -= value; }
  63. }
  64. public string ApplyPolicy(string assemblyName)
  65. {
  66. if (assemblyName == null)
  67. {
  68. throw new ArgumentNullException(nameof(assemblyName));
  69. }
  70. if (assemblyName.Length == 0 || assemblyName[0] == '\0')
  71. {
  72. throw new ArgumentException(SR.Argument_StringZeroLength, nameof(assemblyName));
  73. }
  74. return assemblyName;
  75. }
  76. public static AppDomain CreateDomain(string friendlyName)
  77. {
  78. if (friendlyName == null) throw new ArgumentNullException(nameof(friendlyName));
  79. throw new PlatformNotSupportedException(SR.PlatformNotSupported_AppDomains);
  80. }
  81. public int ExecuteAssembly(string assemblyFile) => ExecuteAssembly(assemblyFile, null);
  82. public int ExecuteAssembly(string assemblyFile, string?[]? args)
  83. {
  84. if (assemblyFile == null)
  85. {
  86. throw new ArgumentNullException(nameof(assemblyFile));
  87. }
  88. string fullPath = Path.GetFullPath(assemblyFile);
  89. Assembly assembly = Assembly.LoadFile(fullPath);
  90. return ExecuteAssembly(assembly, args);
  91. }
  92. public int ExecuteAssembly(string assemblyFile, string?[]? args, byte[]? hashValue, Configuration.Assemblies.AssemblyHashAlgorithm hashAlgorithm)
  93. {
  94. throw new PlatformNotSupportedException(SR.PlatformNotSupported_CAS); // This api is only meaningful for very specific partial trust/CAS scenarios
  95. }
  96. private int ExecuteAssembly(Assembly assembly, string?[]? args)
  97. {
  98. MethodInfo? entry = assembly.EntryPoint;
  99. if (entry == null)
  100. {
  101. throw new MissingMethodException(SR.Arg_EntryPointNotFoundException);
  102. }
  103. object? result = entry.Invoke(
  104. obj: null,
  105. invokeAttr: BindingFlags.DoNotWrapExceptions,
  106. binder: null,
  107. parameters: entry.GetParameters().Length > 0 ? new object?[] { args } : null,
  108. culture: null);
  109. return result != null ? (int)result : 0;
  110. }
  111. public int ExecuteAssemblyByName(AssemblyName assemblyName, params string?[]? args) =>
  112. ExecuteAssembly(Assembly.Load(assemblyName), args);
  113. public int ExecuteAssemblyByName(string assemblyName) =>
  114. ExecuteAssemblyByName(assemblyName, null);
  115. public int ExecuteAssemblyByName(string assemblyName, params string?[]? args) =>
  116. ExecuteAssembly(Assembly.Load(assemblyName), args);
  117. public object? GetData(string name) => AppContext.GetData(name);
  118. public void SetData(string name, object? data) => AppContext.SetData(name, data);
  119. public bool? IsCompatibilitySwitchSet(string value)
  120. {
  121. bool result;
  122. return AppContext.TryGetSwitch(value, out result) ? result : default(bool?);
  123. }
  124. public bool IsDefaultAppDomain() => true;
  125. public bool IsFinalizingForUnload() => false;
  126. public override string ToString() =>
  127. SR.AppDomain_Name + FriendlyName + Environment.NewLine + SR.AppDomain_NoContextPolicies;
  128. public static void Unload(AppDomain domain)
  129. {
  130. if (domain == null)
  131. {
  132. throw new ArgumentNullException(nameof(domain));
  133. }
  134. throw new CannotUnloadAppDomainException(SR.Arg_PlatformNotSupported);
  135. }
  136. public Assembly Load(byte[] rawAssembly) => Assembly.Load(rawAssembly);
  137. public Assembly Load(byte[] rawAssembly, byte[]? rawSymbolStore) => Assembly.Load(rawAssembly, rawSymbolStore);
  138. public Assembly Load(AssemblyName assemblyRef) => Assembly.Load(assemblyRef);
  139. public Assembly Load(string assemblyString) => Assembly.Load(assemblyString);
  140. public Assembly[] ReflectionOnlyGetAssemblies() => Array.Empty<Assembly>();
  141. public static bool MonitoringIsEnabled
  142. {
  143. get { return true; }
  144. set
  145. {
  146. if (!value)
  147. {
  148. throw new ArgumentException(SR.Arg_MustBeTrue);
  149. }
  150. }
  151. }
  152. public long MonitoringSurvivedMemorySize => MonitoringSurvivedProcessMemorySize;
  153. public static long MonitoringSurvivedProcessMemorySize
  154. {
  155. get
  156. {
  157. GCMemoryInfo mi = GC.GetGCMemoryInfo();
  158. return mi.HeapSizeBytes - mi.FragmentedBytes;
  159. }
  160. }
  161. public long MonitoringTotalAllocatedMemorySize => GC.GetTotalAllocatedBytes(precise: false);
  162. [ObsoleteAttribute("AppDomain.GetCurrentThreadId has been deprecated because it does not provide a stable Id when managed threads are running on fibers (aka lightweight threads). To get a stable identifier for a managed thread, use the ManagedThreadId property on Thread. https://go.microsoft.com/fwlink/?linkid=14202", false)]
  163. public static int GetCurrentThreadId() => Environment.CurrentManagedThreadId;
  164. public bool ShadowCopyFiles => false;
  165. [ObsoleteAttribute("AppDomain.AppendPrivatePath has been deprecated. Please investigate the use of AppDomainSetup.PrivateBinPath instead. https://go.microsoft.com/fwlink/?linkid=14202")]
  166. public void AppendPrivatePath(string? path) { }
  167. [ObsoleteAttribute("AppDomain.ClearPrivatePath has been deprecated. Please investigate the use of AppDomainSetup.PrivateBinPath instead. https://go.microsoft.com/fwlink/?linkid=14202")]
  168. public void ClearPrivatePath() { }
  169. [ObsoleteAttribute("AppDomain.ClearShadowCopyPath has been deprecated. Please investigate the use of AppDomainSetup.ShadowCopyDirectories instead. https://go.microsoft.com/fwlink/?linkid=14202")]
  170. public void ClearShadowCopyPath() { }
  171. [ObsoleteAttribute("AppDomain.SetCachePath has been deprecated. Please investigate the use of AppDomainSetup.CachePath instead. https://go.microsoft.com/fwlink/?linkid=14202")]
  172. public void SetCachePath(string? path) { }
  173. [ObsoleteAttribute("AppDomain.SetShadowCopyFiles has been deprecated. Please investigate the use of AppDomainSetup.ShadowCopyFiles instead. https://go.microsoft.com/fwlink/?linkid=14202")]
  174. public void SetShadowCopyFiles() { }
  175. [ObsoleteAttribute("AppDomain.SetShadowCopyPath has been deprecated. Please investigate the use of AppDomainSetup.ShadowCopyDirectories instead. https://go.microsoft.com/fwlink/?linkid=14202")]
  176. public void SetShadowCopyPath(string? path) { }
  177. public Assembly[] GetAssemblies() => AssemblyLoadContext.GetLoadedAssemblies();
  178. public event AssemblyLoadEventHandler? AssemblyLoad
  179. {
  180. add { AssemblyLoadContext.AssemblyLoad += value; }
  181. remove { AssemblyLoadContext.AssemblyLoad -= value; }
  182. }
  183. public event ResolveEventHandler? AssemblyResolve
  184. {
  185. add { AssemblyLoadContext.AssemblyResolve += value; }
  186. remove { AssemblyLoadContext.AssemblyResolve -= value; }
  187. }
  188. public event ResolveEventHandler? ReflectionOnlyAssemblyResolve;
  189. public event ResolveEventHandler? TypeResolve
  190. {
  191. add { AssemblyLoadContext.TypeResolve += value; }
  192. remove { AssemblyLoadContext.TypeResolve -= value; }
  193. }
  194. public event ResolveEventHandler? ResourceResolve
  195. {
  196. add { AssemblyLoadContext.ResourceResolve += value; }
  197. remove { AssemblyLoadContext.ResourceResolve -= value; }
  198. }
  199. public void SetPrincipalPolicy(PrincipalPolicy policy)
  200. {
  201. _principalPolicy = policy;
  202. }
  203. public void SetThreadPrincipal(IPrincipal principal)
  204. {
  205. if (principal == null)
  206. {
  207. throw new ArgumentNullException(nameof(principal));
  208. }
  209. lock (_forLock)
  210. {
  211. // Check that principal has not been set previously.
  212. if (_defaultPrincipal != null)
  213. {
  214. throw new SystemException(SR.AppDomain_Policy_PrincipalTwice);
  215. }
  216. _defaultPrincipal = principal;
  217. }
  218. }
  219. public ObjectHandle? CreateInstance(string assemblyName, string typeName)
  220. {
  221. if (assemblyName == null)
  222. {
  223. throw new ArgumentNullException(nameof(assemblyName));
  224. }
  225. return Activator.CreateInstance(assemblyName, typeName);
  226. }
  227. public ObjectHandle? CreateInstance(string assemblyName, string typeName, bool ignoreCase, BindingFlags bindingAttr, Binder? binder, object?[]? args, System.Globalization.CultureInfo? culture, object?[]? activationAttributes)
  228. {
  229. if (assemblyName == null)
  230. {
  231. throw new ArgumentNullException(nameof(assemblyName));
  232. }
  233. return Activator.CreateInstance(assemblyName,
  234. typeName,
  235. ignoreCase,
  236. bindingAttr,
  237. binder,
  238. args,
  239. culture,
  240. activationAttributes);
  241. }
  242. public ObjectHandle? CreateInstance(string assemblyName, string typeName, object?[]? activationAttributes)
  243. {
  244. if (assemblyName == null)
  245. {
  246. throw new ArgumentNullException(nameof(assemblyName));
  247. }
  248. return Activator.CreateInstance(assemblyName, typeName, activationAttributes);
  249. }
  250. public object? CreateInstanceAndUnwrap(string assemblyName, string typeName)
  251. {
  252. ObjectHandle? oh = CreateInstance(assemblyName, typeName);
  253. return oh?.Unwrap();
  254. }
  255. public object? CreateInstanceAndUnwrap(string assemblyName, string typeName, bool ignoreCase, BindingFlags bindingAttr, Binder? binder, object?[]? args, System.Globalization.CultureInfo? culture, object?[]? activationAttributes)
  256. {
  257. ObjectHandle? oh = CreateInstance(assemblyName,
  258. typeName,
  259. ignoreCase,
  260. bindingAttr,
  261. binder,
  262. args,
  263. culture,
  264. activationAttributes);
  265. return oh?.Unwrap();
  266. }
  267. public object? CreateInstanceAndUnwrap(string assemblyName, string typeName, object?[]? activationAttributes)
  268. {
  269. ObjectHandle? oh = CreateInstance(assemblyName, typeName, activationAttributes);
  270. return oh?.Unwrap();
  271. }
  272. public ObjectHandle? CreateInstanceFrom(string assemblyFile, string typeName)
  273. {
  274. return Activator.CreateInstanceFrom(assemblyFile, typeName);
  275. }
  276. public ObjectHandle? CreateInstanceFrom(string assemblyFile, string typeName, bool ignoreCase, BindingFlags bindingAttr, Binder? binder, object?[]? args, System.Globalization.CultureInfo? culture, object?[]? activationAttributes)
  277. {
  278. return Activator.CreateInstanceFrom(assemblyFile,
  279. typeName,
  280. ignoreCase,
  281. bindingAttr,
  282. binder,
  283. args,
  284. culture,
  285. activationAttributes);
  286. }
  287. public ObjectHandle? CreateInstanceFrom(string assemblyFile, string typeName, object?[]? activationAttributes)
  288. {
  289. return Activator.CreateInstanceFrom(assemblyFile, typeName, activationAttributes);
  290. }
  291. public object? CreateInstanceFromAndUnwrap(string assemblyFile, string typeName)
  292. {
  293. ObjectHandle? oh = CreateInstanceFrom(assemblyFile, typeName);
  294. return oh?.Unwrap();
  295. }
  296. public object? CreateInstanceFromAndUnwrap(string assemblyFile, string typeName, bool ignoreCase, BindingFlags bindingAttr, Binder? binder, object?[]? args, System.Globalization.CultureInfo? culture, object?[]? activationAttributes)
  297. {
  298. ObjectHandle? oh = CreateInstanceFrom(assemblyFile,
  299. typeName,
  300. ignoreCase,
  301. bindingAttr,
  302. binder,
  303. args,
  304. culture,
  305. activationAttributes);
  306. return oh?.Unwrap();
  307. }
  308. public object? CreateInstanceFromAndUnwrap(string assemblyFile, string typeName, object?[]? activationAttributes)
  309. {
  310. ObjectHandle? oh = CreateInstanceFrom(assemblyFile, typeName, activationAttributes);
  311. return oh?.Unwrap();
  312. }
  313. internal IPrincipal? GetThreadPrincipal()
  314. {
  315. IPrincipal? principal = _defaultPrincipal;
  316. if (principal == null)
  317. {
  318. switch (_principalPolicy)
  319. {
  320. case PrincipalPolicy.UnauthenticatedPrincipal:
  321. if (s_getUnauthenticatedPrincipal == null)
  322. {
  323. Type type = Type.GetType("System.Security.Principal.GenericPrincipal, System.Security.Claims", throwOnError: true)!;
  324. MethodInfo? mi = type.GetMethod("GetDefaultInstance", BindingFlags.NonPublic | BindingFlags.Static);
  325. Debug.Assert(mi != null);
  326. // Don't throw PNSE if null like for WindowsPrincipal as UnauthenticatedPrincipal should
  327. // be available on all platforms.
  328. Volatile.Write(ref s_getUnauthenticatedPrincipal,
  329. (Func<IPrincipal>)mi.CreateDelegate(typeof(Func<IPrincipal>)));
  330. }
  331. principal = s_getUnauthenticatedPrincipal();
  332. break;
  333. case PrincipalPolicy.WindowsPrincipal:
  334. if (s_getWindowsPrincipal == null)
  335. {
  336. Type type = Type.GetType("System.Security.Principal.WindowsPrincipal, System.Security.Principal.Windows", throwOnError: true)!;
  337. MethodInfo? mi = type.GetMethod("GetDefaultInstance", BindingFlags.NonPublic | BindingFlags.Static);
  338. if (mi == null)
  339. {
  340. throw new PlatformNotSupportedException(SR.PlatformNotSupported_Principal);
  341. }
  342. Volatile.Write(ref s_getWindowsPrincipal,
  343. (Func<IPrincipal>)mi.CreateDelegate(typeof(Func<IPrincipal>)));
  344. }
  345. principal = s_getWindowsPrincipal();
  346. break;
  347. }
  348. }
  349. return principal;
  350. }
  351. }
  352. }