Служба Windows: можно ли настроить текущий рабочий каталог?

11

По умолчанию службы Windows запускаются в каталоге sytem32 (обычно C:\WINDOWS\system32).

Есть ли способ настроить другой рабочий каталог? Я думаю о каком-то параметре реестра ниже HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SomeService.

Итак, можно ли это сделать?

Томалак
источник
3
@ Томалак: Это сервис, который вы написали? Вы можете сделать это с помощью кода, но я не думаю, что есть способ через настройки сервиса.
MattB
Нет, это не сервис, который я написал. Я надеялся, что некоторые малоизвестные настройки реестра здесь.
Томалак
Какова цель сделать это?
user35115
@ user35115: Ну, если честно ... Обнаружив несвязанную проблему с procmon, я заметил, что определенная служба ввода-вывода (полнотекстовый индексатор) постоянно проверяет свои собственные файлы в неправильных местах (довольно глупо). Он начинается с system32, пробует еще несколько мест и, в конце концов, свой собственный каталог. Я подумал, что когда он сразу запустится в своем собственном каталоге, он сделает меньше ненужных проверок файлов. Не то чтобы это не сработало в настоящее время, но заставило меня задуматься, есть ли место для улучшений.
Томалак
1
@ user35115, чтобы избежать массового изменения настроек конфигурации определенного приложения (скажем, Apache и т. д.), которые все относятся к рабочему каталогу.
Pacerier

Ответы:

5

Вы можете использовать DLL-инъекцию для вызова SetCurrentDirectoryпосле того, как процесс уже запущен. Это потребует от вас создания приложения-инжектора, а также DLL для внедрения. Существуют некоторые учебные пособия; вероятно, два лучших из них я нашел:

Для этого вам понадобится приличный опыт программирования на C ++ (и рабочая среда сборки).

Однако это предполагает, что служба просматривает текущий каталог. Другая возможность заключается в том, что он использует %path%. Вы говорите, что он «начинается system32, пробует еще несколько мест и, в конечном итоге, свой собственный каталог», так что мне это кажется более вероятным.

Сравните каталоги, которые вы видите procmonс вашими %path%. Если они одинаковы, рассмотрите возможность изменения пользователя SYSTEM %path%или %path%пользователя, запустившего службу, так, чтобы каталог, который вы хотите найти, был первым.

Однако я считаю, что Фред прав - вы вряд ли увидите какую-либо значительную выгоду в производительности, если не будете делать это очень часто. Простые операции открытия файлов не особенно дороги, особенно если это локальный путь, а файл на самом деле не существует.

расщепление
источник
Системная переменная окружения PATH была первым, что пришло мне в голову. Однако вставка пути службы в начале переменной PATH отрицательно повлияет на производительность практически всех других приложений, поэтому я бы не советовал этого делать.
Марникс ван Вален
В любом случае у меня нет точных цифр, подтверждающих это, но моя интуиция подсказывает мне, что при изменении пути не будет никакого практического увеличения или потери производительности. Это довольно распространенный сценарий; никто не обвиняет, скажем, средства поддержки Windows или SQL Server, в том, что они отрицательно влияют на производительность системы, когда она изменяет путь во время установки. Это не первый раз, когда я вижу, как кто-то смотрит на procmon и говорит: «О боже, посмотрите на все эти обращения к файлам!», Не понимая, что это типично для большинства приложений.
деление
+1 за креативность. :-) Я полностью понимаю, что эти файловые операции не оказывают существенного влияния на производительность, поэтому я не собираюсь на самом деле беспокоиться о написании решения для инъекции DLL. %PATH%Тем не менее, изменение учетной записи, под которой работает служба, - неплохая идея.
Томалак
1
Создание специального пользователя для запуска только этой службы и изменение% PATH% для этого пользователя звучит как очень хороший путь. +1
солнечный
@fission: Да, это значит, что я принимаю твой ответ. ;) Это не то, на что я надеялся, но это настолько близко, насколько это возможно, я думаю.
Томалак
1

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

Фред
источник
1

Добавьте строковое значение «AppDirectory» в ключ параметров и установите желаемое значение рабочего каталога.

отметка
источник
Гектометр Только что протестировано, похоже, не работает (В Windows 7 используется тип данных REG_EXPAND_SZ). Не могли бы вы подтвердить, что это действительно работает для вас, пожалуйста?
Томалак
Это работает при использовании srvany. Не уверен насчет нормальных услуг.
Константин Спирин
1

Сделайте это в основной функции сервиса:

  • Позвони GetModuleFilename. Он извлечет имя файла модуля (exe), включая путь, в форме C:\path\to\exe\your_service.exe.
  • Используйте манипуляции со строками (возможно, используя std::stringфункцию find_last_of()), чтобы найти последний обратный слеш. Отрежьте / обрежьте строку оттуда, чтобы получить путь к вашему модулю и, следовательно, каталог вашего exe-файла.
  • Сделай вызов функции SetCurrentDirectoryи вуаля!
uprightech
источник
1
не забудьте передать значение null параметру HMODULE в вызове функции GetModuleFilename :)
uprightech