Запуск приложения из службы Windows приводит к неопределенному выходу из системы - PullRequest
0 голосов
/ 16 января 2020

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

Моя проблема заключается в том, что при выходе из системы на секунду В то время как служба работает, выход не завершается sh, но оставляет меня с черным экраном и курсором мыши. Я могу выйти один раз и снова войти в систему, позволяя приложению перезапуститься, но не снова, пока я не перезагружусь (принудительно); Я не могу запустить диспетчер задач или показать экран Ctrl-Alt-Delete .

Я бы слил приложение с сервисом, но для этого требуется активное взаимодействие с пользователем. Мой код построен с Windows SDK 10.0.17134.0. Ниже приведена упрощенная версия моей функции:

BOOL LaunchApp(PROCESS_INFORMATION& ProcessInfo)
{
  LPCWSTR lpApplicationName = L"C:\\Program Files (x86)\\AppName\\application.exe";
  LPCWSTR lpCurrentDirectory = L"C:\\Program Files (x86)\\AppName\\";

  STARTUPINFOW StartupInfo;

  ZeroMemory(&ProcessInformation, sizeof(PROCESS_INFORMATION));
  ZeroMemory(&StartupInfo, sizeof(StartupInfo));
  StartupInfo.cb = sizeof(StartupInfo);
  StartupInfo.lpDesktop = L"winsta0\\default";

  auto sessionId = ::WTSGetActiveConsoleSessionId();
  auto userToken = ::GetUserToken(sessionId);
  if (userToken)
  {
    LPVOID pEnv;
    if (::CreateEnvironmentBlock(&pEnv, userToken.get(), TRUE/*inherit*/))
    {
      BOOL createResult = ::CreateProcessAsUserW(userToken, lpApplicationName, NULL,
                                                NULL/*procAttrs*/, NULL/*threadAttrs*/,
                                                FALSE/*InheritHandles*/, CREATE_UNICODE_ENVIRONMENT,
                                                pEnv, lpCurrentDirectory,
                                                &StartupInfo, &ProcessInfo);
      // NOTE: handles placed in 'ProcessInfo' are closed outside function
      ::DestroyEnvironmentBlock(pEnv);

      return createResult;
    }
  }
  return false;
}

Что может быть причиной моей проблемы? Есть какой-то ресурс, о чьей ручке я не знаю? Есть ли другой способ сделать то, что я хочу?

...