Example #1
0
        /// <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);
        }
Example #2
0
 /// <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));
        }