Как заставить деинсталляцию службы Windows

174

Я установил службу Windows, используя installUtil.exe.

После обновления кода я снова использовал installUtil.exe, чтобы установить службу без удаления исходной версии.

Когда я сейчас пытаюсь удалить службу, installUtil.exe успешно завершает удаление, но служба все равно появляется.

Если я пытаюсь изменить его свойства, я получаю сообщение «Сервис помечен для удаления».

Как я могу форсировать удаление (желательно без перезагрузки сервера)?

Manu
источник
Если служба зависает, а удаление не работает, см. Как принудительно удалить службу Windows
Вернфрид Домшайт

Ответы:

470

Одна вещь, которая меня поразила в прошлом, это то, что если у вас запущен просмотрщик сервисов, то это предотвращает полное удаление сервисов, поэтому закройте это заранее

the_mandrill
источник
70
Я с трудом могу поверить в то, что если у зрителя открытая программа, удаление службы прерывается - как глупо!
Draemon
1
Это так глупо от Microsoft, но это действительно работает. По какой-то необъяснимой причине открытое средство просмотра служб иногда препятствует их правильному удалению.
Иван
1
Я думаю, что этот ответ будет иметь сотни подобных комментариев. Я только что потерял 30 минут из-за этой глупой проблемы ...
PierrOz
2
Кажется, что SysInternals Process Explorer также блокирует службы (и, возможно, также диспетчер задач), поэтому убедитесь, что вы тоже их закрыли!
Данио
3
также убедитесь, что вы используете командную строку cmd. PowerShell не показывает никаких ошибок, но также не удаляет.
Бруно Фариа
145

Вам не нужно перезагружать свою машину. Запустите cmd или PowerShell в режиме повышенных прав.

sc.exe queryex <SERVICE_NAME>

Тогда вы получите некоторую информацию. Номер PID покажет.

taskkill /pid <SERVICE_PID> /f

Где / f, чтобы заставить остановиться.

Теперь вы можете установить или запустить свой сервис.

Johan
источник
2
Работал беспечно, где все остальное, кроме перезагрузки не удалось - хорошо, доволен!
DaveF
36
Это не сработало для меня - pid для моего сервиса вернул 0, и это не позволило бы мне удалить критический системный процесс.
plasma147
4
А + классно. Используйте sc delete, затем выше.
Zone12
7
не работал, поскольку PID пришел как 0, это решило мою проблему - (SC) DeleteService FAILED 1072
Web-E
3
Абсолютно полезно! В моем случае ничего кроме перезагрузки не сработало. Даже не удаляя каталог службы в реестре! Один Гоча , хотя: Если вы работаете в использовании PowerShell: sc.exe queryex <SERVICENAME>. Поскольку scэто также псевдоним для Set-Content, он будет молча терпеть неудачу, когда вы используете это.
Ифеди Оконкво
97

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

sc delete <Service_Name>

Узнайте больше о "MS Techno Blogging", принудительно удаляя службы из служб MMC


источник
5
Спасибо за это. Обратите внимание, что если «Имя службы» не совпадает с «Отображаемым именем», вы можете получить «Имя службы» в свойствах службы.
GuiSim
8
sc deleteтакже сообщит, что «сервис помечен для удаления», если для сервиса открыт дескриптор.
Мэтт
@GuiSim спасибо за это, я подозреваю, что многие будут отображать отображаемое имя, как я!
nik0lai
Попытался, но получил это сообщение: [SC] DeleteService FAILED 1072: Указанная служба была помечена для удаления.
Эндрю В. Филлипс
37

Я знаю, что это не поможет, но это может помочь кому-то в будущем.

У меня была та же проблема: закрытие и повторное открытие менеджера сервисов удалило запись из реестра и завершило удаление сервиса.

До этого обновление менеджера сервисов не помогло.

Kennifer
источник
1
Спасибо за участие. Мой опыт был именно таким, как вы описали.
шт.
10
sc delete sericeName

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

Аарон Вайкер
источник
Просто дополнение ... Мне пришлось запустить приглашение dos / .NET от имени администратора, чтобы получить доступ к команде sc delete ... на тот случай, если кто-нибудь еще столкнется с этой проблемой.
Dav.id
Запустите «NET STOP <serviceName>» перед SC DELETE, чтобы убедиться, что служба была остановлена ​​перед удалением
Adi
Это был и мой опыт, мне в конечном итоге пришлось перезагрузиться, чтобы удалить упрямый сервис, который был только частично удален (он все еще отображался в оснастке с кодом 2). Перезагрузка была тем, что, наконец, заставило его уйти.
delliottg
5

Закройте окно cmd и службы, если оно открыто, затем снова запустите cmd, щелкнув правой кнопкой мыши и выбрав команду «Запуск от имени администратора». Если sc delete sericeNameне работает или ничего не работает.

http://weblogs.asp.net/avnerk/archive/2007/09/05/windows-services-services-msc-and-the-quot-this-service-is-marked-for-deletion-quot-error. ASPX

неполный
источник
4

К сожалению, вам нужно перезагрузить сервер. Это должно удалить «удаленный» сервис.

seanyboy
источник
12
Нет. Вам не нужно перезапускать. Смотрите мое решение :)
Йохан
2
Мне на самом деле нравится решение user186749 еще лучше. Красиво и чисто.
Маккей,
3

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

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

загар
источник
3

Вы можете вручную удалить раздел реестра для своей службы, расположенный по адресу HKLM\SYSTEM\CurrentControlSet\Services, после чего вы не увидите службу в диспетчере управления службами (необходимо обновить или открыть заново, чтобы увидеть изменения), и вы можете переустановить службу как обычно.

Фернандо Гонсалес Санчес
источник
В Windows 2012 R2 заставка оснастки MMC служб (Services.MSC) отображает сообщение « Не удалось прочитать описание. Код ошибки: 2 ». Несмотря на то, что все остальные консоли MMC были закрыты, другие пользователи не входили в систему.
Сигнал15
Я вижу, проверено только в Windows 8 и Windows 10 (и это сработало).
Фернандо Гонсалес Санчес
Это наконец решило мою проблему. Я забыл добавить установщик службы в проект и не смог удалить службу после установки. Я рекомендую сделать экспорт дерева сервисных рег, прежде чем что-либо удалять из него. Большое спасибо!
user3772108
2

Следующее будет работать без перезагрузки машины:

  1. Поиск в реестре \ HKEY_LOCAL_MACHINE по <имени вашей службы> (ключам и значениям)
  2. Установите значение "Legacy" в 0
Дмитрий
источник
1

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

дефектный
источник
1

Я опоздал, но хотел бы добавить альтернативу, которая может выглядеть странно, но я не видел другого пути:

Поскольку я устанавливал свои службы Windows в процессе CI каждую ночь, мне нужно было что-то, что работает постоянно и полностью автоматизировано. По какой-то причине службы всегда были отмечены для удаления в течение длительного времени (5 минут и более) после их удаления. Поэтому я расширил пакетный скрипт переустановки, чтобы убедиться, что служба действительно удалена (упрощенная версия):

REM Stop the service first
net stop My-Socket-Server

REM Same as installutil.exe, just implemented in the service
My.Socket.Server.exe /u

:loop1
    REM Easy way to wait for 5 seconds
    ping 192.0.2.2 -n 1 -w 5000 > nul
    sc delete My-Socket-Server
    echo %date% %time%: Trying to delete service.
    if errorlevel 1072 goto :loop1

REM Just for output purposes, typically I get that the service does not exist
sc query My-Socket-Server

REM Installing the new service, same as installutil.exe but in code
My.Socket.Server.exe /i

REM Start the new service
net start My-Socket-Server

Что я вижу, так это то, что сервис помечен для удаления примерно на 5 минут (!), Пока, наконец, не пройдет. Наконец, мне не нужно больше ручных вмешательств. Я буду расширять сценарий в будущем, чтобы что-то происходило через определенное время (например, уведомление через 30 минут).

марко
источник
1

Это сработало для меня

$a = Get-WmiObject Win32_Service | Where-Object {$_.Name -eq 'psexesvc'}
$a.Delete()
expirat001
источник
Если ваш вывод показывает ReturnValue : 16, что команда завершилась неудачно с « Эта служба удаляется из системы ». Полный список ReturnValues ​​от Microsoft здесь
Signal15
1

Если вы не можете остановить службу в Службах , вы можете остановить свою службу Windows exe в диспетчере задач . После этого вы можете удалить сервис.

Огужан киркали
источник
0

Обновление списка услуг всегда делало это для меня. Если окно служб открыто, то по какой-то причине оно будет содержать некоторую память о нем. F5 и я снова переустанавливаю!

Иер
источник
0

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

Я открывал и закрывал MMC и искал PID для уничтожения, но при поиске в проводнике процессов было несколько существующих процессов, запущенных из забытого запланированного пакета. Убил их. Работа выполнена.

Unsliced
источник
0

В этой теме множество вопросов на форуме.

Я нашел ответ в Windows API. Вам не нужно перезагружать компьютер после удаления службы. Вы должны позвонить:

BOOL WINAPI CloseServiceHandle(
  SC_HANDLE hSCObject
);

Это закрывает ручку службы. На Windows 7 это решило мою проблему. Я делаю:

  • остановить сервис
  • закрыть ручку
  • удалить службу
  • подождите 3 сек
  • скопировать новый exe в каталог
  • установить сервис
  • начать обслуживание
  • закрыть ручку
Габор Балаз
источник
2
Где вы получаете ручку для закрытия, если вы не в программе, которая имеет открытую ручку?
Мэтт
0

Я использую следующий PowerShell, собранный из нескольких мест для наших экземпляров Octopus Deploy, когда TopShelf выходит из строя или происходит сбой службы по какой-либо другой причине.

$ServiceName = 'MyNaughtyService'
$ServiceName | Stop-Service -ErrorAction SilentlyContinue
# We tried nicely, now KILL!!!
$ServiceNamePID = Get-Service | Where { $_.Name -eq $ServiceName} # If it was hung($_.Status -eq 'StopPending' -or $_.Status -eq 'Stopping') -and
$ServicePID = (Get-WmiObject Win32_Service | Where {$_.Name -eq $ServiceNamePID.Name}).ProcessID
Stop-Process $ServicePID -Force
dragon788
источник
0

Также стоит отметить, что это:

sc delete "ServiceName"

не работает в PowerShell, sc является псевдонимом для командлета Set-Content в PowerShell. Вам нужно сделать:

sc.exe delete "ServiceName"
Ричард
источник