Как я могу получить путь к исполняемому файлу службы Windows, не используя sc qc?

15

Мне нужно запросить службу Windows для пути к ее исполняемому через командную строку. Я думаю, что я бы сделал это так:, sc qc myServiceNameно когда я это сделаю, я получу следующую ошибку:

[SC] QueryServiceConfig FAILED 122:

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

[SC] GetServiceConfig требуется 1094 байта

Я думаю, это означает, что команда sc отправляет структуру данных в другую библиотеку, которая слишком мала для данных, которые необходимо вернуть. Вместо того, чтобы SC аккуратно повторял попытку с большей структурой данных (1094 байта), он взрывается и выдает мне это ужасное сообщение об ошибке. Спасибо Micro $ oft.

Так есть ли способ обойти эту ошибку? Мне просто нужен путь к исполняемому файлу, но при необходимости я буду анализировать его из некоторого другого текста.

Джаред
источник

Ответы:

20

Я также столкнулся с этой проблемой, когда пытался узнать подробности службы, где путь к исполняемому файлу был очень длинным. Это обсуждение содержит обходной путь; Вы можете передать размер буфера в качестве аргумента sc qc. То есть, если вы делаете:

sc qc <service name> 5000

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


Также см. Страницу SC QC MSDN:

sc [<ServerName>] qc [<ServiceName>] [<BufferSize>]

где:

<BufferSize> Определяет размер (в байтах) буфера. Размер буфера по умолчанию составляет 1024 байта.

Кен Кинан
источник
2
К вашему сведению, 2^13 = 8192это максимальное значение для размера буфера.
Небфа
sc queryex type= service state= all | find /i "myServiceNameперечисляет все услуги, но, к сожалению, нет пути.
Шаян
13

Я нашел работоспособное решение:

reg query "HKLM\System\CurrentControlSet\Services\<serviceName>" /v "ImagePath"

Конечно, это требует некоторого разбора, но он дает мне полный путь, который предоставляет диалоговое окно services.msc.

Джаред
источник
10

Вы можете сделать это в PowerShell с помощью запроса WMI, например:

$service = get-wmiobject -query 'select * from win32_service where name="winrm"'; echo $service.pathname

Это даст вам полный путь, включая параметры, как они показаны в services.msc. Просто замените winrmв моем примере любую службу, которую вы хотите найти.

Приведенный выше запрос winrmдолжен выводитьC:\Windows\System32\svchost.exe -k NetworkService

MDMarra
источник
К сожалению, я не могу зависеть от powershell, поскольку в XP его нет по умолчанию. Мне нужна поддержка XP, server 2008 и 7 без установки какого-либо дополнительного программного обеспечения.
Джаред
@ Джаред, это очень плохо. Вы не можете запустить это с одной машины на кучу удаленных машин?
MDMarra
Нет, это на самом деле немного скрипта, чтобы войти в программу удаления приложения. Я нашел решение, которое работает, и добавил ответ на него.
Джаред
4

Попробуйте это с помощью wmicутилиты командной строки. Вот пример службы на моей машине под названием CrashPlanService.

C:\Users\Ben>wmic service CrashPlanService get PathName

PathName
"C:\Program Files\CrashPlan\CrashPlanService.exe"

В основном wmic service <<YourService>> get PathName.

Бен Пилброу
источник
1
Не совсем работает Но, с другой стороны, это работает: "wmic service | find" <servicename> "
djangofan
@djangofan какой выход вы получаете, и с каким сервисом? Может быть, у вас есть другая версия wmic(я на Windows 7 SP1)?
Бен Пилброу
@Ben Pilbrow Это тоже не сработало для меня. wmic не получает имя пути (просто возвращает «PathName», в следующей строке ничего не указано). Не уверен, что это потому, что в пути много параметров, что делает его очень длинным.
Джаред
работал для меня, но мне пришлось немного обработать результат: ((wmic service SQLBrowser get PathName) -match " "")[0].replace("" "," ")
katbyte
wmic serviceпрекрасно работает. Перечисляет все службы с их путями.
Шаян