2
0

AppDomain.cs 18 KB

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