Win8.1 будет запускать событие разгрузки и загрузки в приложение WPF, когда мы закрываем и подключаемся к этой машине с помощью RDC из win7 или другой ОС

Это странная проблема только в Win8.1.

Как мы все знаем, если на компьютере есть работающее приложение, при подключении/отключении/повторном подключении к этой машине с помощью подключения к удаленному рабочему столу не должно быть никаких других действий против приложения. Однако мы обнаружили, что Win8.1 будет запускать выгрузку и загрузку событий в приложение WPF, когда мы закроем и снова подключимся к машине с помощью RDC. И это нежелательное поведение, которое может вызвать ошибку.

Вот стабильные шаги воспроизведения:

  • Напишите приложение WPF, которое содержит кнопку и обрабатывает события выгрузки и загрузки этой кнопки.
  • Использование RDC для подключения к Win8.1 из Win7, например.
  • На удаленном рабочем столе запустите это приложение WPF (событие загрузки будет записано в a.txt).
  • Закройте RDC, щелкнув "x".
  • Подключитесь к этому Win8.1 снова.
  • Вы увидите, что были запущены события разгрузки и загрузки.

Если приложение WPF запускается на Win7 или Win Server 2008, эти события не будут запущены.

Итак, я думаю, что это нежелательное поведение в Win8.1. Это ошибка в Win8.1 RDP? Или это новая функция?

Ответ 1

Это происходит потому, что повторное подключение RDP уведомляет код WPF о том, что сеансовое приложение изменило сеанс и экран. WPF необходимо перестроить свои ресурсы DirectX и, вероятно, обработать обновленный размер экрана (хотя разрешение может быть одинаковым). Это имеет смысл b/c, клиент RDP может указывать различные возможности, такие как уровень графики и другие свойства на вкладке "Опыт" RDP. WPF не определяет, что параметры все те же, что и в последний раз, когда произошло соединение, и запускает новый цикл рендеринга и компоновки (имеет смысл, поскольку цвета и разрешение экрана могут быть изменены). Это приводит к перезагрузке элементов управления и новому запуску события Loaded.

Вы можете увидеть многое из подробностей этого вопроса, изучив HwndTarget.cs в источнике .NET. Найдите этот файл для "session", и вы увидите LOT обработки для отключения сеанса/повторного подключения.

http://referencesource.microsoft.com/#PresentationCore/Core/CSharp/System/Windows/Interop/HwndTarget.cs,f20f989ef219e391

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

Вы можете увидеть, что происходит, добавив точку останова в обработчик событий Loaded и перейдите в "Инструменты" > "Параметры", "Отладка" и "Отключить только мой код" и установите флажок "Включить стекирование исходного кода .NET" и установите флажок "Включить Source Server". Когда вы подключаете RDP, bkpt будет запускаться, и стек вызовов покажет событие изменения размера среди других уровней вызовов. Вероятно, это связано с тем, что WPF получает WM_DISPLAYCHANGE, а также все ре-макет в случае более или менее разрешающего действия с этим соединением.