在WPF中逐步运行Powershell脚本文件(C#)

问题描述 投票:0回答:2

我是 C# 新手,并且在 WPF 中有一个 GUI,在某些时候它应该自动开始执行 Powershell 脚本,但最好是一个接一个地执行。正如我看到所有方法立即运行而无需等待前一个方法完成,所以我的问题是:使用某种线程或异步方法哪个更好?

如果我尝试使用task.WaitForExit();然后它会冻结 GUI,这是不可接受的。我也尝试过使用计时器,但看起来它根本没有看到这一点。另外我还有比较多的ps1文件和几个bat文件,需要一一运行。 您能告诉我在这种情况下使用哪种方法更好以及如何将其与主动 GUI 结合起来吗?

public partial class Start_deployment : Window
{
    public Start_deployment()
    {
        InitializeComponent();
        Run_scripts();
        System.Windows.Application.Current.Shutdown();
    }

    public void Run_scripts()
    {
        var ps1File = @"C:\test\Install.ps1";
        var startInfo = new ProcessStartInfo()
        {
            FileName = "powershell.exe",
            Arguments = $"-ExecutionPolicy Bypass -WindowStyle Hidden -NoProfile -file \"{ps1File}\"",
            UseShellExecute = false
        };
        var task = Process.Start(startInfo);
        //task.WaitForExit();
    }

    private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
    {

    }
}
c# wpf multithreading powershell asynchronous
2个回答
1
投票

Process.Start()
返回
Process
实例,该实例具有 Exited 事件。订阅该活动以在结束时收到通知:

public partial class Start_deployment : Window
{
    public Start_deployment()
    {
        InitializeComponent();
        Run_scripts();
    }

    public void Run_scripts()
    {
        var ps1File = @"C:\test\Install.ps1";
        var startInfo = new ProcessStartInfo()
        {
            FileName = "powershell.exe",
            Arguments = $"-ExecutionPolicy Bypass -WindowStyle Hidden -NoProfile -file \"{ps1File}\"",
            UseShellExecute = false
        };
        var proc = Process.Start(startInfo);
        proc.Exited += OnProcessExited;
    }

    private void OnProcessExited(object sender, EventArgs eventArgs)
    {            
        // todo, e.g.
        // System.Windows.Application.Current.Shutdown();
    }
}

0
投票

我没有 50 名代表在已接受的答案中发表评论,所以我在这里这样做。

对于任何希望 OnProcessExited 工作的人,您需要“proc.EnableRaisingEvents = true;”。我在某个地方找到了它。下面是我的代码。

    private void Run_scripts_2()
    {
        var ps1File = scriptPath;
        var startInfo = new ProcessStartInfo()
        {
            FileName = "powershell.exe",
            Arguments = $"-ExecutionPolicy Bypass -WindowStyle Hidden -NoProfile -file \"{ps1File}\" \"{HostName}\" \"{DatabaseName}\" \"{GetFileNamePath()}\"",
            UseShellExecute = false
        };
        var proc = Process.Start(startInfo);
        proc.EnableRaisingEvents = true;
        proc.Exited += new EventHandler(OnProcessExited);
    }

    private void OnProcessExited(object sender, EventArgs eventArgs)
    {
        ToggleGrandGrid(true);

        if (dispatcherTimer != null && dispatcherTimer.IsEnabled) 
        { 
            dispatcherTimer.Stop(); 
        }

        if(stopWatch != null && stopWatch.IsRunning) 
        {
            stopWatch.Stop();
        }

        UpdateBackupScript($"OnProcessExited(..) - StopWatch.Elapsed = [{stopWatch.Elapsed}]");

        theLog?.logger.LogDebug("PS Script Done");
    }
© www.soinside.com 2019 - 2024. All rights reserved.