Process.Start с UseShellExecute не удается вывести окно notepad.exe на передний план после предыдущего закрытия окна - PullRequest
0 голосов
/ 25 февраля 2020

Я пытаюсь использовать Process.Start (with UseShellExecute=true) для создания экземпляра notepad.exe. Приведенный ниже код выполняется внутри COM-объекта, вызываемого другой программой (программой голосового ввода).

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

    Win32.PostMessage(Hwnd, WM_SYSCOMMAND, SC_CLOSE, 0);

Второй способ закрытия окна блокнота

Основное стороннее голосовое программное обеспечение также предоставляет команду «закрыть окно», которая закрывает окно блокнота, когда оно находится на переднем плане. Этот метод закрытия экземпляра блокнота является частью проблемы.

Проблема

Проблема в том, что после закрытия блокнота с помощью голосовой команды «закрыть окно» при следующей операции открытия открывается блокнот но не выводит это на первый план. Он открывается за Outlook или Chrome и отображается на панели задач. По какой-то причине код Process.Start не выводит экземпляр блокнота на передний план после закрытия блокнота командой «закрыть окно». Я не понимаю почему. Код Process.Start не должен знать, как (или если) был закрыт предыдущий экземпляр блокнота.

Приведенный ниже код пытается SetWindowPos выдвинуть окно блокнота на передний план / верх в случае Process.Start не выполнил задание, но код SetWindowPos никогда не завершается сбоем, и окно сообщения об ошибке никогда не появляется, даже когда возникает проблема. (SetWindowPos - только побочная проблема, поскольку код нормально работает с сообщениями WM_CLOSE.)

Воспроизводится на моей машине

Вот типичный шаблон, который я зарегистрировал на своей машине. FChrome / FOutlook означает Chrome или Outlook были передним планом windows для эксперимента (оба были опробованы с одинаковыми результатами). No = блокнот открыт, N c = блокнот закрыт (как указано выше), CW = «закрыть окно», а NoXX означает сбой (блокнот не отображается в качестве верхнего окна переднего плана).

Sequences of operations: open, close, open, "close window", open (notepad open fails NoXX)
FChrome, No, Nc, No, CW, NoXX
FOutlook, No, Nc, No, CW, NoXX

Кто-нибудь знает, почему метод закрытия окна (возможно, SendMessage или Win32.WindowDestroy?) может Process.Start не вывести новый экземпляр Блокнота на передний план?

    // record name of foreground window before the operation
    var forehandle = GetForegroundWindow ();
    var forenamebefore = WinFuns.GetForegroundWindow ().Title;

    // create process to start notepad
    var psi = new ProcessStartInfo ();
    psi.UseShellExecute = true;
    psi.FileName = "notepad.exe";
    var proc = Process.Start (psi);
    Thread.Sleep (2000);

    // get foreground process name after Process.Start - it should be notepad
    proc.Refresh (); // refresh before retrieving the handle
    IntPtr prochandle = (IntPtr)proc.MainWindowHandle;
    var forenameafter = WinFuns.GetForegroundWindow ().Title;

    // get the process name of this code
    var myhandle = Process.GetCurrentProcess ().MainWindowHandle;
    var myname = (new WindowHandle (myhandle)).Title;

    // ensure the notepad instance is on top
    bool r;
    var p = new IntPtr (0);
    r = Win32.SetWindowPos (prochandle, p, 0, 0, 0, 0, 3); //window on top
    if (!r) MessageBox.Show ($"Failed to set top window position.");

    // show before/after/mynames after the operation is complete
    var msg = $"Foreground before: {forenamebefore}\n" +
              $"Foreground after: {forenameafter}\n" +
              $"My name is:       {myname}";
    MessageBox.Show (msg);

1 Ответ

0 голосов
/ 03 марта 2020

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

Однако со временем мой код увеличивался в размере, так как я проверял каждый код ошибки Win32 после каждой операции Win32 и повторял его, повторяя цикл и повторяя попытки при необходимости или необходимости.

Я пришел к выводу, что проверка каждого кода ошибки Win32 для каждой операции и повторение неудачных операций каждые 100 миллисекунд выявляли некоторые неудачные операции, но не решали исходную проблему.

...