C # Служба Windows, которая запускает проблему установки пакета - PullRequest
1 голос
/ 02 апреля 2011

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

У меня проблемы с запуском установщика, поэтому я решил вместо того, чтобы пытаться запустить установщик, запустить маленькое приложение hello world для Windows Forms, чтобы посмотреть, работает ли эта простая вещь.

ПослеЧерез пару часов я наконец-то обнаружил, что приложение hello world на самом деле работает, но под другим пользователем - в частности, на локальной машине.В следующие пару часов я узнал, что мне нужно отключить UAC (Vista / 7) и позволить службе взаимодействовать с рабочим столом.После этого на моем рабочем столе наконец-то появилось сообщение о том, что служба пытается что-то запустить, и мне нужно было решить, разрешить это или нет.

Когда я нажимаю Разрешить - меня переводят в другой графический интерфейс (другойс моего рабочего стола), и привет мир после этого будет работать нормально.

Теперь, хотя это, безусловно, прогресс, я все еще далеко от установки приложения под текущей учетной записью пользователя.

Одной из проблем, с которыми я столкнулся, была настройка службы Windows для запуска от имени определенного пользователя, когда я использую installutil.exe на такого рода WS, он запрашивает у меня имя пользователя и пароль, я ввожу правильный (adminи не удается установить.

Я хочу добиться, чтобы служба Windows установила пакет автоматической установки без прерывания работы пользователя, тестовый пакет автоматической установки - это net framework 2.0 - Iнужно установить его так, как если бы пользователь щелкнул по нему сам.

Мне не нужен код (но это было бы желательно), просто укажите мне правильное направление, заранее спасибо!

Ответы [ 2 ]

1 голос
/ 02 апреля 2011

Вы найдете достаточно подробное объяснение , почему вы видите поведение, которое вы описываете в моих ответах здесь и здесь , если вы 'любопытно.

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

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

1 голос
/ 02 апреля 2011

Я не знаю, как это делается в C #, но я объясню концепцию.

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

Кроме того, из win7 локальные учетные записи служб не могут отображать графический интерфейс из-за серьезных проблем безопасности, таких как запуск приложения cmd.exe, любого вида проводника, который позволяет пользователю выполнять вещи, которые он / она не предполагает делать (я думаю, Вы можете обойти это, не уверен, но в любом случае это не рекомендуется, так что не надо).

Итак, у вас есть 2 варианта:

  1. создайте другое приложение, которое будет работать во время сеанса пользователя, и вы можете общаться с ним с помощью RPC (например, .Net remoting). Вы можете разместить приложение при запуске пользователя.

  2. Лучше, на мой взгляд, использовать CreateProcessAsUser () (я не знаю, как это называется в C #). У каждого пользователя есть токен, поскольку вы являетесь службой, у вас есть разрешение на получение основного токена пользователя, который позволит вам создавать процессы под учетной записью пользователя. CreateProcessAsUser () создает процесс, а также получает токен для запуска процесса от имени этого пользователя.

Еще несколько вещей о токенах, для CreateProcessAsUser вам нужно получить токен пользователя. Самый простой способ сделать это с помощью службы Windows (и только службы Windows) - использовать WTSQuestUserToken. Вы передаете функции sessionID сеанса пользователя и получаете основной токен.

Этот метод НЕ идеален, но в большинстве случаев он прост и подходит. Это не будет работать, если есть 2 пользователя с одинаковым идентификатором сеанса (ID сеанса = идентификатор сеанса сервера терминалов), что можно сделать с помощью запуска от имени из проводника. Но я думаю, что я получил этот ответ достаточно сложным, так что если вы WTSQueryUserToken () недостаточно для вас, дайте мне знать, и я объясню более подробно (и, очевидно, он будет более сложным).

Удачи!

...