EnumDesktopWindows в Windows Service - PullRequest
2 голосов
/ 14 марта 2011

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

У меня проблема в том, что API-вызов EnumDesktopWindows возвращает только процессы, запущенные в контексте локальной системы.

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

Однако как же тогда выполнить эту функцию через службу?

Это основы кода, который я использую:

        public static IntPtr[] EnumDesktopWindows()
        {
            WinAPI._desktopWindowHandles = new List<IntPtr>();
            WinAPI.EnumDelegate enumfunc = new WinAPI.EnumDelegate(EnumWindowsCallBack);
            IntPtr hDesktop = IntPtr.Zero; // current desktop
            bool success = WinAPI.EnumDesktopWindows(hDesktop, enumfunc, IntPtr.Zero);

            if (success)
            {
                IntPtr[] handles = new IntPtr[_desktopWindowHandles.Count];
                _desktopWindowHandles.CopyTo(handles);
                return handles;
            }
            else
            {
                int errorCode = Marshal.GetLastWin32Error();
                string errorMessage = String.Format("EnumDesktopWindows failed with code {0}.", errorCode);
                throw new Exception(errorMessage);
            }

        }

Может быть, у меня все это неправильно, и проблема в линии?:

IntPtr hDesktop = IntPtr.Zero;

Ответы [ 3 ]

5 голосов
/ 14 марта 2011

Службы запускаются в другом сеансе (сеанс 0) от интерактивных пользователей.Это называется изоляцией сеанса 0.

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

Эту проблему необходимо решить путем перечисления процессов, а не окон.

2 голосов
/ 14 марта 2011

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

Если у вас нет способа получить токен пользователя, я бы порекомендовал вам прочитать Влияние изоляции сеанса 0 на службы и драйверы в документе Windows перед продолжением.Основная проблема, с которой вы столкнулись, заключается в том, что службы терминалов работают на компьютере, а ваша служба Windows работает в сеансе с SessionId = 0, но все пользовательские процессы выполняются в другом сеансе.Если ваша служба работает под учетной записью LocalSystem или под любой другой учетной записью, имеющей привилегию SE_TCB_NAME, она может использовать функцию SetTokenInformation с параметром TokenSessionId для перехода на текущий сеанс (см. здесь Больше подробностей).Все доступные сеансы, которые вы можете получить в отношении функции LsaEnumerateLogonSessions .

В конце я могу повторить еще раз, что вам следует изменить сеанс службы, только если другие более простые способы, такие каколицетворение пользователя не может быть использовано.

2 голосов
/ 14 марта 2011
  • Перечисление процессов
  • Приложение должно объявить о присутствии (именованный объект ядра, например, из CreateEvent)
  • Попытаться открыть файл EXE исключительно
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...