// Parse a string specifying a list of assemblies and types // containing a startup hook, and call each hook in turn. private static void ProcessStartupHooks() { // Initialize tracing before any user code can be called. System.Diagnostics.Tracing.RuntimeEventSource.Initialize(); string?startupHooksVariable = (string?)AppContext.GetData("STARTUP_HOOKS"); if (startupHooksVariable == null) { return; } char[] disallowedSimpleAssemblyNameChars = new char[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar, ' ', ',' }; // Parse startup hooks variable string[] startupHookParts = startupHooksVariable.Split(Path.PathSeparator); StartupHookNameOrPath[] startupHooks = new StartupHookNameOrPath[startupHookParts.Length]; for (int i = 0; i < startupHookParts.Length; i++) { string startupHookPart = startupHookParts[i]; if (string.IsNullOrEmpty(startupHookPart)) { // Leave the slot in startupHooks empty (nulls for everything). This is simpler than shifting and resizing the array. continue; } if (Path.IsPathFullyQualified(startupHookPart)) { startupHooks[i].Path = startupHookPart; } else { // The intent here is to only support simple assembly names, but AssemblyName .ctor accepts // lot of other forms (fully qualified assembly name, strings which look like relative paths and so on). // So add a check on top which will disallow any directory separator, space or comma in the assembly name. for (int j = 0; j < disallowedSimpleAssemblyNameChars.Length; j++) { if (startupHookPart.Contains(disallowedSimpleAssemblyNameChars[j])) { throw new ArgumentException(SR.Format(SR.Argument_InvalidStartupHookSimpleAssemblyName, startupHookPart)); } } if (startupHookPart.EndsWith(DisallowedSimpleAssemblyNameSuffix, StringComparison.OrdinalIgnoreCase)) { throw new ArgumentException(SR.Format(SR.Argument_InvalidStartupHookSimpleAssemblyName, startupHookPart)); } try { // This will throw if the string is not a valid assembly name. startupHooks[i].AssemblyName = new AssemblyName(startupHookPart); } catch (Exception assemblyNameException) { throw new ArgumentException(SR.Format(SR.Argument_InvalidStartupHookSimpleAssemblyName, startupHookPart), assemblyNameException); } } } // Call each hook in turn foreach (StartupHookNameOrPath startupHook in startupHooks) { CallStartupHook(startupHook); } }
public object GetData(string name) => AppContext.GetData(name);