C # - дождаться завершения процесса и закрыть ShowDialog () - PullRequest
0 голосов
/ 01 февраля 2019

Будучи новичком в .net, я не могу понять, как закрыть модальное окно диалога после его открытия.Как я узнал, мы не можем закрыть это автоматически до тех пор, пока его явно не вызовут.Вот мой код:

//process - notepad.exe 
Process p = Process.Start(process); 
frm_Save fsave = new frm_Save(); 

Using (p)
{ 
    do
    { 
        if(!p.HasExited)    
        {
            p.Refresh();
            fsave.ShowDialog(); // it just stuck here and doesn't go to next line
        }
    } 
    while(!p.WaitForExit(1000)); 
}

//frm_Save.cs 
public frm_Save() 
{ 
    InitializeComponent(); 
}

private void frm_Save_Load(...,....)
{ 
    // 
}

private void frm_Save_Shown(...,...) 
{ 
    Sleep(100); 
    Forms.Application.DoEvents();
    Close(); 
}

Ответы [ 2 ]

0 голосов
/ 01 февраля 2019

Как вы объяснили, вы хотите показать диалоговое окно со значком, что вы сохраняете видео в фоновом режиме и не позволяете пользователю что-то делать.Один из обычных способов сделать это с помощью BackgroundWorker в вашем диалоге.Вот код, как это будет работать:

public class frm_Save : Form
{
    public FrmProgress(List<TransferOptions> transferOptions)
    {
        InitializeComponent();
        BackgroundWorker BgrdWorker = new System.ComponentModel.BackgroundWorker();
        this.BgrdWorker.DoWork += new System.ComponentModel.DoWorkEventHandler(this.BgrdWorker_DoWork);
        this.BgrdWorker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.BgrdWorker_RunWorkerCompleted);
    }

    private void FrmProgress_Load(object sender, EventArgs e)
    {
        // Show image and message...
    }

    private void BgrdWorker_DoWork(object sender, DoWorkEventArgs e)
    {
        // Call your video Process start Function
        // after that
        var stopWatch = new StopWatch();
        stopWatch.Start()
        while (true)
        {
            if (stopWatch.ElapsedMilliseconds >1000 || videoProcessHasReturnedSuccessfully)
            {
                break
            }
        }
    }

    private void BgrdWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        // inform the user the video processing is finished
        this.Close();
    }
}

Затем в основной форме вашего консольного приложения, когда вы хотите запустить весь процесс, вы вызываете:

frm_Save fsave = new frm_Save(); 
fsave.ShowDialog()

Совет:Вы также можете использовать BgrdWorker.ProgressChanged, чтобы показать ход выполнения фоновой задачи пользователю, связываясь между фоновой задачей и пользовательским интерфейсом, если это необходимо, но вы не запросили об этом в своем вопросе.

0 голосов
/ 01 февраля 2019

Этот подход может работать для вас, обратите внимание на использование TopMost.

using System.Runtime.InteropServices; 

private static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
private const UInt32 SWP_NOSIZE = 0x0001;
private const UInt32 SWP_NOMOVE = 0x0002;
private const UInt32 TOPMOST_FLAGS = SWP_NOMOVE | SWP_NOSIZE;   

[DllImport("user32.dll")] 
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, 
  int X, int Y, int cx, int cy, uint uFlags);

....

frm_Save fsave = new frm_Save(); 
fsave.Show();

SetWindowPos(frm_Save.Handle, HWND_TOPMOST, 0, 0, 0, 0, TOPMOST_FLAGS);

Process p = Process.Start(process); 

using (p)
{
    while (!p.WaitForExit(1000))
    {
        fsave.Refresh();
    }
}
fsave.Close();
...