Отправка сообщения в приложение, запущенное на вторичной учетной записи пользователя, вошедшего в систему. - PullRequest
11 голосов
/ 26 февраля 2012

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

Фон в том, что мое приложение может само обновляться, но для этого все работающие экземпляры должны быть сначала закрыты.
Экземпляры должны быть закрыты (вместо того, чтобы просто убивать процесс), поэтому программа обновления делает это, отправляя им собственное сообщение (с SendMessage). Для того чтобы отправить сообщение мне нужен дескриптор главного окна процесса.

Это прекрасно работает при использовании EnumWindows - если экземпляры работают под одной учетной записью пользователя, поскольку EnumWindows не отображает окна, принадлежащие другому пользователю.

Так что я попробовал другой подход. Я использовал CreateToolhelp32Snapshot, чтобы сначала перечислить все запущенные процессы в системе, а затем перебирать потоки, вызывая CreateToolhelp32Snapshot снова. С этими идентификаторами потоков я мог бы затем перечислить их окна, используя EnumThreadWindows.

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

Итак, как я могу получить дескриптор главного окна моего приложения, работающего под другой зарегистрированной учетной записью пользователя?

Ответы [ 3 ]

10 голосов
/ 26 февраля 2012

Используйте то, что, как известно, работает между сессиями;Подобные вещи часто используются для связи с настольными службами, поэтому поищите их, если хотите, чтобы Google.Вот мое предложение:

  1. Создайте событие, которое будет использоваться только для запуска состояния «необходимо отключить».Используйте функцию CreateEvent , чтобы ваше имя начиналось с Global\, чтобы оно действовало между сеансами.
  2. При запуске приложения создайте поток, который открывает именованное событие (использует тот же CreateEventфункция, обратите пристальное внимание на ERROR_ALREADY_EXISTS не ошибка).Этот поток должен просто ждать события.Когда событие сработает, отправьте нужное сообщение в главное окно.Этот поток может легко и безопасно сделать это, потому что он запускает внутри вашего процесса.Поток будет в основном бездействовать, ожидая, когда событие будет запущено, поэтому не беспокойтесь о потере процессора.
  3. Программа обновления вашего приложения должна просто вызвать указанное событие.

Этоэто только одна идея, я уверен, что есть и другие.

7 голосов
/ 26 февраля 2012

Трубы излишни. Глобального события ручного сброса (например, «Global \ MyApplicationShutdownEvent»), которое приводит к самоуничтожению экземпляров приложения, должно быть достаточно.

0 голосов
/ 27 февраля 2012

Риск быть осмеянным, вы смотрели на zeroMQ , это идеальное использование для него, и оно очень надежное и стабильное.

Существует Оболочка Delphi

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...