0

有没有办法找到使用 ImportPSModule() 导入到 InitialSessionState 中的函数?

我有这个围绕 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() 导入这些函数。最后,我希望能够将 UI 中的这些命令列为可用命令。

我创建了一个非常简单的模块(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.

所以我将把这个问题稍微更新为“有没有办法从可以添加到 initialSessionState.Commands 的脚本文件中创建 SessionStateCommandEntry()?”

4

0 回答 0