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

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

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

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

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

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

edit2: ОС — Windows 2003 Server, обновлять ее не планируется.


person Paul Nathan    schedule 30.04.2009    source источник


Ответы (5)


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

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

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

person Reed Copsey    schedule 30.04.2009
comment
Сервер - Win2K3, и он может оставаться таким. Указанная цель заключается в том, что предпочтительным методом является запуск приложения в качестве службы. - person Paul Nathan; 30.04.2009

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

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

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

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

person Joshua Belden    schedule 30.04.2009
comment
отредактировано для ясности. Безопасность определенно является проблемой здесь. - person Paul Nathan; 30.04.2009

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

person Dmitri Kouminov    schedule 30.04.2009

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

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

person ReinstateMonica Larry Osterman    schedule 01.05.2009

Это код, который я использовал в прошлом, чтобы сделать это в службе управления задачами, которой иногда нужно было запускать что-то в интерактивном сеансе. Замените 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.
   }
}

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

person Bob Moore    schedule 27.09.2016