Правильный способ удаления службы Windows?

У меня есть служба Windows, созданная с использованием С#, которая устанавливается через проект установки VS2008, и у меня возникли проблемы с процессом удаления:

Служба не останавливается перед удалением

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

(В настоящее время мне приходится прибегать к его удалению вручную, используя sc-имя-сервис).

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

protected override void OnBeforeUninstall(IDictionary savedState)
{
   base.OnBeforeUninstall(savedState);
   ServiceController serviceController = new ServiceController(MyInstaller.ServiceName);
   serviceController.Stop();
}

Когда вызывается этот код и как я могу остановить службу до удаления?

Папка установки не удалена после удаления

Приложение также создает некоторые файлы внутри папки установки при выполнении. После удаления папка установки (C:\Program Files\MyApp) не удаляется и содержит файлы, созданные приложением, хотя все другие файлы, которые были фактически установлены установщиком, были успешно удалены.

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

Спасибо.

Ответы

Ответ 1

В интересах любого, кто ищет ответ на эти проблемы:

Служба не останавливается перед удалением

Пока не найдено решение.

Папка установки не удалена после удаления

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

protected override void OnAfterUninstall(IDictionary savedState)
{
    base.OnAfterUninstall(savedState);

    string targetDir = Context.Parameters["TargetDir"]; // Must be passed in as a parameter

    if (targetDir.EndsWith("|"))
        targetDir = targetDir.Substring(0, targetDir.Length-1);

    if (!targetDir.EndsWith("\\"))
        targetDir += "\\";

    if (!Directory.Exists(targetDir))
    {
        Debug.WriteLine("Target dir does not exist: " + targetDir);
        return;
    }

    string[] files = new[] { "File1.txt", "File2.tmp", "File3.doc" };
    string[] dirs  = new[] { "Logs", "Temp" };

    foreach (string f in files)
    {
        string path = Path.Combine(targetDir, f);

        if (File.Exists(path))
            File.Delete(path);
    }

    foreach (string d in dirs)
    {
        string path = Path.Combine(targetDir, d);

        if (Directory.Exists(d))
            Directory.Delete(d, true);
    }

    // At this point, all generated files and directories must be deleted.
    // The installation folder will be removed automatically.
}

Помните, что папка установки должна быть передана как параметр:

  • Щелкните правой кнопкой мыши на проекте настройки, затем выберите "Вид" → "Пользовательские действия"
  • Пользовательские действия откроются в главном окне. Щелкните правой кнопкой мыши "Первичный вывод из XXX" в разделе "Удалить" node и выберите "Окно свойств"
  • В окне свойств в разделе CustomActionData введите следующее:/TargetDir = "[TARGETDIR] |" (обратите внимание на трубку в конце, не удаляйте ее).

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

Ответ 2

Скорее всего, услуга просто занимает немного времени, чтобы завершить работу, и вы продолжаете работу до того, как служба полностью остановится. Попробуйте вызвать метод WaitForStatus (ServiceControllerStatus).

Это приведет к тому, что ваш код будет ждать, пока служба не обработает сообщение "stop" и выключится. Как только служба фактически отключится, она больше не будет удерживаться на каких-либо файлах.