1

我正在编写代码来与 PowerShell 交互。我最初有以下内容:

using (var runspace = RunspaceFactory.CreateRunspace(initialSessionState))
{
    runspace.Open();

这段代码工作得很好。但是,由于这段代码实际上已经在异步方法中,所以我编写了以下代码只是为了进行实验:

public static Task OpenTaskAsync(this Runspace runspace)
{
    if (runspace.RunspaceStateInfo.State == RunspaceState.Opened)
        return Task.FromResult<object>(null);

    var tcs = new TaskCompletionSource<object>();
    EventHandler<RunspaceStateEventArgs> stateHandler = null;
    stateHandler = (o, e) =>
    {
        if (e.RunspaceStateInfo.Reason != null)
        {
            runspace.StateChanged -= stateHandler;
            tcs.TrySetException(e.RunspaceStateInfo.Reason);
        }
        else if (e.RunspaceStateInfo.State == RunspaceState.Opened)
        {
            runspace.StateChanged -= stateHandler;
            tcs.TrySetResult(null);
        }
    };
    runspace.StateChanged += stateHandler;
    runspace.OpenAsync();

    return tcs.Task;
}

但是,在将我的代码更改为此之后:

using (var runspace = RunspaceFactory.CreateRunspace(initialSessionState))
{
    await runspace.OpenTaskAsync();

我的测试现在失败了。原因是 PowerShell 无法再从导入到我的 InitialSessionState 的模块中找到命令(在创建运行空间之前)。我无法确定这是为什么。我已经调试并且运行空间在此任务完成后打开并且可用,并且在它完成之前我不会继续调用任何命令。有任何想法吗?

4

1 回答 1

1

我查看了反射器中的运行空间开放代码,并看到了一件事可以解释它。如果在导入模块LocalRunspace.DoOpenHelper()之前StateChanged发生(当状态更改为“已打开”)看起来您可以轮询正在设置的默认驱动器 (in InitialSessionState.SetSessionStateDrive()) 作为解决方法。

于 2013-07-18T02:10:44.090 回答