C#:PowerShell脚本的启动不会从Form应用程序执行

时间:2018-04-06 12:21:36

标签: c# .net powershell

我正在编写一个执行powershell脚本的实用程序应用程序,该脚本在从共享位置复制文件后进一步启动基于.msi的安装。使用Powershell类异步调用此脚本。
这在控制台应用程序中工作正常,但在通过按钮单击从C#表单调用时挂起。 这是执行Form:

            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(true);
            Application.Run(new frm_MyApp_Update());

以下是用于调用Powershell脚本的方法:

 private void ExecutePSFile(string scriptFile)
    {

        using (PowerShell PowerShellInstance = PowerShell.Create())
        {
            // use "AddScript" to add the contents of a script file to the end of the execution pipeline.
            // use "AddCommand" to add individual commands/cmdlets to the end of the execution pipeline.
            PowerShellInstance.AddScript(System.IO.File.ReadAllText(scriptFile));

            //Synchronus call
            //var psoutput = PowerShellInstance.Invoke();

            // prepare a new collection to store output stream objects
            PSDataCollection<PSObject> outputCollection = new PSDataCollection<PSObject>();

            //Invoking ASynchrounsly, so that we can do something else, while it is being executed in a separate thread.
            IAsyncResult result = PowerShellInstance.BeginInvoke<PSObject, PSObject>(null, outputCollection);

            //let's do something else, while script is bing executed.
            while (result.IsCompleted == false)
            {
                //Problem. Result.IsComplete is not getting true here  :(
                Thread.Sleep(1000);
            }

        }
    }

它调用脚本,但然后陷入while(result.IsCompleted == false)循环,即result.IsCompleted在这里没有变为真。 请注意,这在基于控制台的应用程序中正常工作。

以下是此处使用的Powershell脚本:

$fileName="MyInstall.msi"
$sourcePath="\\MyServer\SharedDir\Installers\"
$targetPath=$Env:TEMP + "\My_tmp\"
$logFile=$targetPath + $fileName + ".log"
New-Item -ItemType Directory -Path $targetPath -Force | Out-Null
Write-Host "Grabbing the latest installer..." -ForegroundColor Green
Copy-Item -Path @($sourcePath  + $fileName) -Destination $targetPath -Force  
Write-Host "Executing..." -ForegroundColor Green 
$MsiArguments = @("/i " + """$targetPath\$fileName""" + " /log " + $logFile)
Start-Process "msiexec.exe" -ArgumentList $MsiArguments -Wait
Remove-Item $targetPath -Force -Recurse -ErrorAction Ignore| Out-Null
Write-Host "Finished Installation process..." -ForegroundColor Green

这是表单线程问题吗? 我在基于表单的应用程序中缺少什么?

任何帮助都会非常感激....

1 个答案:

答案 0 :(得分:0)

https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.powershell.begininvoke

“使用BeginInvoke调用时,调用不会  完成直到输入关闭。 BeginInvoke的调用者必须  写入所有输入后关闭输入缓冲区  输入缓冲区。通过调用关闭输入缓冲区  Close()方法。

如果希望此命令作为独立cmdlet执行  (也就是说,仅使用命令行参数),  一定要在调用BeginInvoke()之前调用Close()。除此以外,  该命令将被执行,就像它有外部输入一样。  如果你发现命令没有做任何事情,  这可能是原因。“