/// <summary> /// Create a singleton of PowerShellAssemblyLoadContext. /// Then register to the Resolving event of the load context that loads this assembly. /// </summary> /// <remarks> /// This method is to be used by native host whose TPA list doesn't include PS assemblies, such as the /// in-box Nano powershell, the PS remote WinRM plugin, in-box Nano DSC and in-box Nano SCOM agent. /// </remarks> /// <param name="basePaths"> /// Base directory paths that are separated by semicolon ';'. /// They will be the default paths to probe assemblies. /// </param> public static void SetPowerShellAssemblyLoadContext([MarshalAs(UnmanagedType.LPWStr)]string basePaths) { if (string.IsNullOrEmpty(basePaths)) throw new ArgumentNullException(nameof(basePaths)); PowerShellAssemblyLoadContext.InitializeSingleton(basePaths); }
/// <summary> /// Initialize powershell AssemblyLoadContext and register the 'Resolving' event, if it's not done already. /// If powershell is hosted by a native host such as DSC, then PS ALC might be initialized via 'SetPowerShellAssemblyLoadContext' before loading S.M.A. /// </summary> static ClrFacade() { if (PowerShellAssemblyLoadContext.Instance == null) { PowerShellAssemblyLoadContext.InitializeSingleton(string.Empty); } }
/// <summary> /// Create a singleton of PowerShellAssemblyLoadContext. /// Then call into the actual entry point based on the given assembly name, type name, method name and arguments. /// </summary> /// <param name="basePaths"> /// Base directory paths that are separated by semicolon ';'. /// They will be the default paths to probe assemblies. /// </param> /// <param name="entryAssemblyName"> /// Name of the assembly that contains the actual entry point. /// </param> /// <param name="entryTypeName"> /// Name of the type that contains the actual entry point. /// </param> /// <param name="entryMethodName"> /// Name of the actual entry point method. /// </param> /// <param name="args"> /// An array of arguments passed to the entry point method. /// </param> /// <returns> /// The return value of running the entry point method. /// </returns> public static object InitializeAndCallEntryMethod(string basePaths, AssemblyName entryAssemblyName, string entryTypeName, string entryMethodName, object[] args) { if (string.IsNullOrEmpty(basePaths)) { throw new ArgumentNullException("basePaths"); } if (entryAssemblyName == null) { throw new ArgumentNullException("entryAssemblyName"); } if (string.IsNullOrEmpty(entryTypeName)) { throw new ArgumentNullException("entryTypeName"); } if (string.IsNullOrEmpty(entryMethodName)) { throw new ArgumentNullException("entryMethodName"); } args = args ?? s_emptyArray; var psLoadContext = PowerShellAssemblyLoadContext.InitializeSingleton(basePaths, useResolvingHandlerOnly: false); var entryAssembly = psLoadContext.LoadFromAssemblyName(entryAssemblyName); var entryType = entryAssembly.GetType(entryTypeName, throwOnError: true, ignoreCase: true); var methodInfo = entryType.GetMethod(entryMethodName, BindingFlags.Static | BindingFlags.Public | BindingFlags.IgnoreCase); return(methodInfo.Invoke(null, args)); }
/// <summary> /// Create a singleton of PowerShellAssemblyLoadContext. /// Then register to the Resolving event of the load context that loads this assembly. /// </summary> /// <remarks> /// This method is to be used by native host whose TPA list doesn't include PS assemblies, such as the /// in-box Nano powershell.exe, the PS remote WinRM plugin, in-box Nano DSC and in-box Nano SCOM agent. /// </remarks> /// <param name="basePaths"> /// Base directory paths that are separated by semicolon ';'. /// They will be the default paths to probe assemblies. /// </param> public static void SetPowerShellAssemblyLoadContext([MarshalAs(UnmanagedType.LPWStr)] string basePaths) { if (string.IsNullOrEmpty(basePaths)) { throw new ArgumentNullException("basePaths"); } PowerShellAssemblyLoadContext.InitializeSingleton(basePaths, useResolvingHandlerOnly: true); }
/// <summary> /// Initialize a singleton of PowerShellAssemblyLoadContext /// </summary> internal static PowerShellAssemblyLoadContext InitializeSingleton(string basePaths, bool useResolvingHandlerOnly) { lock (s_syncObj) { if (Instance != null) throw new InvalidOperationException(SingletonAlreadyInitialized); Instance = new PowerShellAssemblyLoadContext(basePaths, useResolvingHandlerOnly); return Instance; } }
/// <summary> /// Initialize a singleton of PowerShellAssemblyLoadContext /// </summary> internal static PowerShellAssemblyLoadContext InitializeSingleton(string basePaths) { lock (s_syncObj) { if (Instance != null) { throw new InvalidOperationException(SingletonAlreadyInitialized); } Instance = new PowerShellAssemblyLoadContext(basePaths); return(Instance); } }
/// <summary> /// Create a singleton of PowerShellAssemblyLoadContext. /// Then load the assembly containing the actual entry point using it. /// </summary> /// <param name="basePaths"> /// Base directory paths that are separated by semicolon ';'. /// They will be the default paths to probe assemblies. /// </param> /// <param name="entryAssemblyName"> /// Name of the assembly that contains the actual entry point. /// </param> /// <returns> /// The assembly that contains the actual entry point. /// </returns> public static Assembly InitializeAndLoadEntryAssembly(string basePaths, AssemblyName entryAssemblyName) { if (string.IsNullOrEmpty(basePaths)) { throw new ArgumentNullException("basePaths"); } if (entryAssemblyName == null) { throw new ArgumentNullException("entryAssemblyName"); } var psLoadContext = PowerShellAssemblyLoadContext.InitializeSingleton(basePaths, useResolvingHandlerOnly: false); return(psLoadContext.LoadFromAssemblyName(entryAssemblyName)); }
/// <summary> /// Create a singleton of PowerShellAssemblyLoadContext. /// Then load System.Management.Automation and call the WSManPluginManagedEntryWrapper delegate. /// </summary> /// <remarks> /// This method is used by the native host of the PSRP plugin. /// </remarks> /// <param name="wkrPtrs"> /// Passed to delegate. /// </param> public static int WSManPluginWrapper(IntPtr wkrPtrs) { string basePaths = System.IO.Path.GetDirectoryName(typeof(PowerShellAssemblyLoadContextInitializer).GetTypeInfo().Assembly.Location); string entryAssemblyName = "System.Management.Automation, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"; string entryTypeName = "System.Management.Automation.Remoting.WSManPluginManagedEntryWrapper"; string entryMethodName = "InitPlugin"; object[] args = { wkrPtrs }; var psLoadContext = PowerShellAssemblyLoadContext.InitializeSingleton(basePaths, useResolvingHandlerOnly: false); var entryAssembly = psLoadContext.LoadFromAssemblyName(new AssemblyName(entryAssemblyName)); var entryType = entryAssembly.GetType(entryTypeName, throwOnError: true, ignoreCase: true); var methodInfo = entryType.GetMethod(entryMethodName, BindingFlags.Static | BindingFlags.Public | BindingFlags.IgnoreCase); return((int)methodInfo.Invoke(null, args)); }