В C# добавьте команды в PowerShell InitialSessionState с помощью скрипта и сделайте их обнаруживаемыми с C#.
Есть ли способ найти функции, которые были импортированы в InitialSessionState с помощью ImportPSModule()?
У меня есть эта оболочка вокруг PowerShell для запуска скриптов, размещенных в моем приложении (комментарии и проверка ошибок удалены для краткости)
public class Engine
{
private readonly InitialSessionState sessionState;
public Engine(string initializationModulePath)
{
this.sessionState = InitialSessionState.CreateDefault();
this.sessionState.LanguageMode = PSLanguageMode.FullLanguage;
this.sessionState.AuthorizationManager = null;
// New functionality - allow an initialization file.
this.sessionState.ImportPSModule(new[] { initializationModulePath });
}
public void AddCommand(String name, Type implementingType) => this.sessionState.Commands.Add(
new SessionStateCmdletEntry(
name,
implementingType,
null));
public void RunScript(string script, string scriptComment)
{
using (PowerShell powerShellCommand = PowerShell.Create())
{
powerShellCommand.AddScript(script);
using (powerShellCommand.Runspace = RunspaceFactory.CreateRunspace(this.sessionState))
{
powerShellCommand.Runspace.Open();
Collection<PSObject> results = powerShellCommand.Invoke();
// Results processing omitted.
}
}
}
// Testing - I see things added via AddCommand() but not anything imported via ImportPSModule
public void ListCommands()
{
foreach (SessionStateCommandEntry commandEntry in this.sessionState.Commands)
{
Console.WriteLine($"Command: {commandEntry.Name}, Type: {commandEntry.CommandType}");
}
}
}
Когда я добавляю типы с помощью engine.AddCommand (), они появляются в engine.ListCommands (), как и ожидалось. Теперь я хочу разрешить пользователям иметь собственный набор функций, которые они предопределили, которые я импортирую через ImportPSModule(). Наконец, я хотел бы иметь возможность перечислить эти команды в пользовательском интерфейсе как доступные команды.
Я создал действительно простой модуль (init.psm1)
function Add-Number {[CmdletBinding()] param ([int]$a, [int]$b) $a + $b }
function Subtract-Number {[CmdletBinding()] param ([int]$a, [int]$b) $a - $b }
и протестировали его импорт, но функции не отображаются как доступные команды. (Хотя пользовательские скрипты могут их прекрасно использовать.)
Я посмотрел на System.Management.Automation.Language.Parser.ParseFile на основе этого вопроса и мог проверить токены после {function}, но это похоже на обходной способ сделать это. (В настоящее время это лучший вариант, который у меня есть.)
Я подумал о том, чтобы запустить небольшой скрипт с
Get-ChildItem function:
, но Get-ChildItem недоступен при использовании
InitialSessionState.CreateDefault()
(Я не хочу использовать
InitialSessionState.Create()
. Мой сценарий требует, чтобы двигатель был более заблокирован, чем это.)
Есть ли другой вариант, который я могу использовать для получения списка пользовательских функций? Их можно импортировать другим способом, если пользователи могут предоставить их в виде кода PowerShell.
Спасибо!
Изменить Перечитав документацию , кажется, я пропустил эту очень важную строчку:
Add a list of modules to import when the runspace is created.
Поэтому я немного обновлю вопрос: «Есть ли способ создать SessionStateCommandEntry () из файла сценария, который можно добавить в initialSessionState.Commands?»