Модальный MessageBox в дескрипторе другого процесса может заблокировать целевой процесс.

StackOverflow https://stackoverflow.com/questions/1259920

Вопрос

Если я показываю MessageBox как модальное окно другого процесса, он работает нормально, пока моя программа продолжает отвечать.Если он закрыт или прекращен, пока MessageBox показывает окна, получившие MessageBox, они будут заблокированы (но все равно будут отвечать), и их придется завершить через диспетчер задач.

Вот пример кода, демонстрирующий это:

using System;
using System.Windows.Forms;
using System.Diagnostics;
using System.Threading;

namespace TestMessageBox
{
    class Program
    {
        private WindowWrapper notepad;

        Program(IntPtr handle)
        { 
            notepad = new WindowWrapper(handle); 
        }

        static void Main(string[] args)
        {
            Process[] procs = Process.GetProcessesByName("notepad");
            if (procs.Length > 0)
            {
                Console.WriteLine("Notepad detected...");
                Program program = new Program(procs[0].MainWindowHandle);
                Thread thread = new Thread(new ThreadStart(program.ShowMessage));
                thread.IsBackground = true;
                thread.Start();
                Console.Write("Press any key to end the program and lock notepad...");
                Console.ReadKey();
            }
        }

        void ShowMessage()
        { 
            MessageBox.Show(notepad, "If this is open when the program ends\nit will lock up notepad..."); 
        }
    }

    /// <summary>
    /// Wrapper class so that we can return an IWin32Window given a hwnd
    /// </summary>
    public class WindowWrapper : System.Windows.Forms.IWin32Window
    {
        public WindowWrapper(IntPtr handle)
        { 
            _hwnd = handle; 
        }
        public IntPtr Handle
        { 
            get { return _hwnd; } 
        }
        private IntPtr _hwnd;
    }

}

Как этого избежать?

Это было полезно?

Решение

При отображении модального диалогового окна отключается родительское окно диалогового окна (окно Блокнота в вашем примере).Когда модальный диалог закрывается, родительское окно снова включается.

Если ваша программа завершится до того, как она снова включит окно, это окно никогда не будет снова включено - повторное включение родителя зависит от потока, который показывает диалог.(В вашем примере это происходит внутри MessageBox.Show(), после того, как пользователь нажмет «ОК» или что-то еще.)

Единственный способ заставить это работать — иметь второй процесс, в обязанности которого входило бы вернуть все в исходное состояние, если процесс, создающий модальный диалог, преждевременно завершится, но это ужасно.И он все еще не является пуленепробиваемым — что, если процесс-наблюдатель тоже умрет?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top