我正在编写一个执行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
这是表单线程问题吗? 我在基于表单的应用程序中缺少什么?
任何帮助都会非常感激....
答案 0 :(得分:0)
https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.powershell.begininvoke
“使用BeginInvoke调用时,调用不会 完成直到输入关闭。 BeginInvoke的调用者必须 写入所有输入后关闭输入缓冲区 输入缓冲区。通过调用关闭输入缓冲区 Close()方法。
如果希望此命令作为独立cmdlet执行 (也就是说,仅使用命令行参数), 一定要在调用BeginInvoke()之前调用Close()。除此以外, 该命令将被执行,就像它有外部输入一样。 如果你发现命令没有做任何事情, 这可能是原因。“