从ASP.NET异步调用powershell脚本

时间:2014-03-26 12:29:45

标签: c# asp.net powershell asynchronous ihttphandler

尝试异步调用ASP.NET IHttHandler中的powershell脚本,我偶然发现http://msdn.microsoft.com/en-us/library/ee706580(v=vs.85).aspx上的示例。我自己的代码如下:

using (PowerShell powershell = PowerShell.Create()) {
    powershell.AddScript("1..10 | foreach {$_ ; start-sleep -milli 500}");

    PSDataCollection<PSObject> output = new PSDataCollection<PSObject>();

    output.DataAdded += delegate(object sender, DataAddedEventArgs e) {
        PSDataCollection<PSObject> myp = (PSDataCollection<PSObject>)sender;
        Collection<PSObject> results = myp.ReadAll();
    };

    powershell.InvocationStateChanged += delegate(object sender, PSInvocationStateChangedEventArgs e) {
        if (e.InvocationStateInfo.State == PSInvocationState.Completed) {
            // Clean up
        }
    };

    IAsyncResult asyncResult = powershell.BeginInvoke<PSObject, PSObject>(null, output);
}

不幸的是,powershell脚本显然没有被执行。任务管理器中都没有显示powershell进程。

我使用DataAddedIncovationStateChanged处理程序设置了断点。第一个永远不会被调用,第二个显示,e.InvocationStateInfo.State永远不会成为Completed,而是以Stopped结束。

我做错了什么?

1 个答案:

答案 0 :(得分:1)

这适用于控制台应用:

using (PowerShell powershell = PowerShell.Create())
{
    powershell.AddScript("1..10 | foreach {$_ ; start-sleep -milli 500}");

    var output = new PSDataCollection<PSObject>();

    output.DataAdded += delegate(object sender, DataAddedEventArgs e)
    {
        Console.WriteLine(output[e.Index]);
        var myp = (PSDataCollection<PSObject>)sender;
        Collection<PSObject> results = myp.ReadAll();
    };

    powershell.InvocationStateChanged += delegate(object sender, PSInvocationStateChangedEventArgs e)
    {
        if (e.InvocationStateInfo.State == PSInvocationState.Completed)
        {
            // Clean up
        }
    };

    IAsyncResult asyncResult = powershell.BeginInvoke<PSObject, PSObject>(null, output);

    asyncResult.AsyncWaitHandle.WaitOne();
}

如果您之后不以某种方式同步或返回并等待调用完成,则PowerShell引擎将关闭,因为powershell.Dispose()会因using {}范围之外而被调用。< / p>