В 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?»

0 ответов

Другие вопросы по тегам