Загрузка приложения с графическим интерфейсом из службы Windows

2

Я пишу службу .NET Windows, роль которой заключается в запуске приложения GUI (источник которого недоступен). Операция - это огонь и забыт, без связи с параметрами командной строки.

Служба должна работать как заданная учетная запись Windows.

Проблема. Приложение, которое запускает служба, не отображается на рабочем столе. Это должно быть, так как это интерактивное приложение. Каково решение?

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

edit: Элементы GUI отображаются корректно, когда регистрируются как учетная запись локальной системы, однако из-за того, что приложение GUI требует доступа к сетевым дискам (оно не может понять UNC-сопоставление), его нужно запускать как заданный пользователь учетной записи и не имеет настройки "отображения интерактивных элементов".

edit2: ОС - это Windows 2003 Server, и нет никаких планов по ее обновлению.

Теги:
service

5 ответов

4

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

В этой статье есть несколько ссылок на пару возможных обходных решений. Вот поток на MSDN, в котором подробно описывается весь процесс и некоторые потенциальные икоты, с которыми вы можете столкнуться.

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

  • 0
    Сервер Win2K3, и он может оставаться таким. Указанная цель заключается в том, чтобы предпочтительным методом было запускать приложение в качестве службы.
0

Это код, который я использовал в прошлом, чтобы сделать это в службе управления задачами, которая иногда необходима для запуска файлов в интерактивном сеансе. Замените wibble.exe своим приложением. Он должен работать нормально на сервере 2003 (т.е. NT5). Мы не пытались заставить интерактивный режим работать на NT6 (слишком много неприятностей), мы оставили наши приложения, запущенные в сеансе службы, и написали нашу собственную утилиту отладки, чтобы поговорить с ними через каналы.

STARTUPINFO  sui ;
PROCESS_INFORMATION pi;

ZeroMemory (&sui, sizeof(STARTUPINFO));
sui.cb = sizeof (STARTUPINFO);
sui.wShowWindow = pTask->GetWinStartState();
sui.dwFlags     = STARTF_USESHOWWINDOW;
ZeroMemory (&pi,sizeof(pi));

if (InteractiveMode)
{
   HANDLE  hToken = NULL;
   DWORD dwSessionId = GetCurrentUserSession();

   if (dwSessionId != (DWORD)-1)
   {
      if (WTSQueryUserToken (dwSessionId, &hToken))
      {
         sui.lpDesktop = TEXT("winsta0\\default");
         LPVOID  pEnv = NULL;
         dwCreateFlags |= CREATE_NEW_CONSOLE;
         HMODULE hModu = LoadLibrary(TEXT("Userenv.dll"));

         if (hModu)
         {
            if (CreateEnvironmentBlock (&pEnv, hToken, FALSE))
            {
               dwCreateFlags |= CREATE_UNICODE_ENVIRONMENT;    
            }
            else
            {
               pEnv = NULL;
            }
         }

         bCreatedOk = CreateProcessAsUser (hToken,
                                           NULL,
                                           TEXT("wibble.exe"),
                                           NULL,
                                           NULL,
                                           FALSE,
                                           dwCreateFlags,
                                           pEnv,
                                           NULL,
                                           &sui,
                                           &pi);
      }
      else
      {
         // error case
      }
   }
   else
   {
      // remote session? error case.
   }
}

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

0

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

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

0

Вы можете использовать бесплатную утилиту Autologon http://technet.microsoft.com/en-us/sysinternals/bb963905.aspx от Sysinternals/Microsoft и добавьте приложение в Startup для профиля пользователя autologon. После этого вы можете настроить серию экрана, чтобы начать через несколько минут, и установите флажок "Вкл. Просмотр, отображение экрана входа в систему".

0

Это удар в темноте, но, надеюсь, приведет вас к некоторому пути к решению.

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

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

Так как служба работает, даже если пользователь не зарегистрирован, что произойдет, если он запустит приложение? Ваши бизнес-правила или функции могут не допустить этого, но, возможно, окна делают что-то, чтобы не работать.

  • 0
    отредактировано для ясности. Безопасность определенно является «проблемой» здесь.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню