Загрузка приложения с графическим интерфейсом из службы Windows - PullRequest
2 голосов
/ 30 апреля 2009

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

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

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

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

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

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

Ответы [ 5 ]

4 голосов
/ 30 апреля 2009

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

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

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

0 голосов
/ 27 сентября 2016

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

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

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

0 голосов
/ 30 апреля 2009

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

0 голосов
/ 30 апреля 2009

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

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

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

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

...