2008-09-22 5 views
2

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

В принципе, допустим, что у пользователя UserA и UserB для UserA служба будет регистрироваться как «domain \ UserA», а для UserB служба будет регистрироваться как «domain \ UserB» - это из того же исполняемого файла курс. Я могу изменить динамический вход в систему с помощью функции ChangeServiceConfig(), но она меняет ее в масштабах всей системы, но я хочу, чтобы каждый пользователь имел свою собственную копию службы, работающей только для него.

Благодарим вас за любые указатели.

ответ

1

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

0

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


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

+0

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

0

Возможно ли, чтобы служба создала дочерние процессы, которые затем принимают учетные данные пользователя (или начинаются с них)? Таким образом, вы по-прежнему ограничены одним экземпляром службы, но все равно можете выполнять задания для каждого пользователя. IIRC, служба Windows Task Scheduler делает это.

+0

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

+0

Возможно. Или, возможно, используя процессы работы (например, использование IE8 и Chrome для вкладок), что, предположительно, снижает некоторые накладные расходы. –

+0

Спасибо - я рассмотрю это как возможность. Интересно, как работает планировщик заданий ... – dennisV

0

Да, это звучит близко (я отвечаю на комментарий Грега, но комментарии слишком короткие, чтобы соответствовать моему ответу).

Я не знаю список пользователей заранее, но есть приложение управления графическим интерфейсом, которое будет использоваться для ввода пар имени пользователя и пароля для каждого пользователя. Таким образом, пользовательA должен войти в систему, запустить приложение, ввести его учетные данные, и служба будет использовать это. В то же время (после того, как пользовательА вышла из системы, но служба по-прежнему работает с учетными данными пользователяA), вход пользователя userB, приложение использует, а другая копия службы запускается как зарегистрированная в userB. Таким образом, одновременно выполняются службы userA и userB.

Возможно ли это?

+0

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

+0

Хм, интересный подход. Мне нужно будет больше исследовать систему планировщика, чтобы убедиться, что она будет работать. Но будет ли он охватывать меня, если никто не войдет в систему? Я не знаю, запускаются ли запланированные задачи без участия пользователя (они должны, я полагаю). – dennisV

+0

Они действительно. Планировщик заданий заботится о настройке правильного контекста пользователя для выполнения задачи, освобождая вас от этой ответственности. –

0

Вы, вероятно, ищете, чтобы олицетворять пользователей. Проверьте некоторые ссылки, которые я нашел с быстрого поиска Google здесь:

+0

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

0

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

  1. Запуск от имени каждого зарегистрированного пользователя
  2. Run автоматически, даже если пользователь не вошел в систему.

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

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

+0

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

+0

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

+0

Если вам действительно нужно это сделать, у вас нет отдельной службы для каждого пользователя - есть единая центральная служба, которая порождает процессы для каждого пользователя по мере необходимости.Набор функций CreateProc позволяет вам определять учетные данные пользователя ... – AviD

0

Вы можете создать приложение-службу и приложение, не относящееся к сервису (нормальное), и заставить их связываться через IPC (Mapped File, Pipes, MailSolts ... вы называете его).

Таким образом, вы решаете все проблемы.

ПРИМЕЧАНИЕ: одно и то же приложение может вести себя по-другому - при запуске как процесс и при запуске пользователем, но в итоге это одно и то же, у вас все еще есть 2 приложения (независимо от того, есть ли у вас только один исполняемый файл) ,

+0

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

0

Возможно использование различных учетных записей. На самом деле это обычное явление. См. Файл svchost.exe, который реализует множество сервисов ОС.

Я просто не понимаю, как вы определяете, какие учетные записи. В большой компании установлено множество компьютеров, поэтому все 100.000 сотрудников могут ее использовать. Вы не хотите запускать свою службу в качестве зарегистрированных пользователей и не хотите запускать ее для всех 100 000 пользователей. Итак, для каких счетов я должен спросить?

+0

Да, это было бы проблемой в такой среде, я согласен. Но это для «домашнего» приложения, поэтому я не ожидаю более 3-4 учетных записей на одной машине, причем наиболее распространенными являются 1 и 2. – dennisV

0

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

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

+0

Спасибо. Я прочитаю об этих атаках. Я также думал об аналогичных запусках дочерних процессов (из одной «центральной» системной службы), которые затем регистрировались бы как пользователи. – dennisV

0

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

Вы можете сделать это, реализовав объект COM, размещенный в службе. Ваше клиентское приложение (которое запускает конечный пользователь) вызовет CoCreateInstanceEx в вашем CLSID. Это приведет к созданию нового экземпляра вашего COM-объекта в вашей службе. Затем приложение может использовать метод на одном из ваших интерфейсов для передачи собранных учетных данных пользователя объекту COM (хотя я бы опасался собирать учетные данные и вместо этого видел, могу ли я передать токен пользователя).COM-объект, который запущен в контексте службы, может затем вызвать LogonUser() для входа в систему пользователя и олицетворения его, поэтому он может делать все, что от ее имени (например, найти локальную папку appdata пользователя :-)). Другие ответы содержат хорошие ссылки на олицетворение пользователей с использованием учетных данных или токенов.

Если вы чувствуете себя комфортно с COM, я бы предложил вам создать ваши объекты как многопоточные (живущие в MTA), чтобы их выполнение не было сериализовано COM. Если нет, модель с одним потоком по умолчанию будет достаточно для вас.

Мастер Visual Studio ATL может генерировать скелет COM-объекта, проживающего в сервисе. Вы также можете прочитать о внедрении Windows Service с ATL: http://msdn.microsoft.com/en-us/library/74y2334x(VS.80).aspx

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

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

+0

Благодарим вас за идею. Вопрос, который у меня есть, заключается в том, как я смогу контролировать, будут ли выполняться службы отдельных пользователей или нет, скажем, UserA хочет запустить службу автоматически, но UserB вручную? Это будет возможно? – dennisV

+0

Чтобы запустить его при входе пользователя в систему, добавьте простой исполняемый файл в HKCU \ Software \ Microsoft \ Windows \ CurrentVersion \ Run. Этот исполняемый файл запустит задание пользователя в вашей службе, как описано выше. –

+0

Чтобы запустить его при загрузке ОС, вам нужно сохранить учетные данные пользователя, чтобы вы могли войти в систему и выдать себя за себя. Я бы этого не сделал, поскольку это привело к серьезным угрозам безопасности. –

0

Вы хотите, чтобы это работало все время, поэтому вам нужна услуга.

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

Смежные вопросы