Отправка сообщения в приложение, запущенное во вторичной учетной записи пользователя

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

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

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

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

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

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

Ответ 1

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

  • Создайте событие, которое будет использоваться только для запуска состояния "необходимо выключить". Используйте CreateEvent, убедитесь, что вы запустили свое имя с помощью Global\, чтобы оно было действительным во всех сеансах.
  • При запуске приложения создайте поток, который открывает именованное событие (использует ту же функцию CreateEvent, обратите пристальное внимание на ERROR_ALREADY_EXISTS non-error). Этот поток должен просто ждать события. Когда событие запускается, отправьте требуемое сообщение в главное окно. Этот поток может легко и безопасно сделать это, потому что он работает внутри вашего процесса. Поток будет в основном бездействовать, ожидая, когда событие будет запущено, поэтому не беспокойтесь о штрафе CPU.
  • Ваш аппликатор приложения должен просто вызвать именованное событие.

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

Ответ 2

Трубы переполнены. Глобальное руководство - reset событие (например, "Global\MyApplicationShutdownEvent" ), которое заставляет экземпляры приложений убивать себя, должно быть достаточно.

Ответ 3

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

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