Как устранить "указанная служба уже существует" при установке новых версий моего программного обеспечения?
У меня есть приложение VS2008, которое включает в себя сервисный проект (я назову его ServiceProject). У меня есть проект установки (InstallationProject), установленный на RemovePreviousVersions. Кроме того, у меня есть пользовательские действия, установленные для InstallationProject, для установки, фиксации, отката и удаления первичного вывода из ServiceProject.
Иногда, когда я собираю новые версии установщика, я могу установить без ошибок. Часто, когда я дохожу до точки настройки службы (ввода имени пользователя и пароля в установщик) - происходит сбой с ошибкой "Указанная служба уже существует".
Я не знаю, почему это противоречиво, хотя я считал, что, возможно, существует какая-то подпись для службы, и если служба не изменена, она может удалить ее успешно, но с изменениями она не распознает оказание услуг. Однако я редко делаю модификации в сервисе, поэтому сомневаюсь, что это так.
Как я могу заставить мой установщик успешно обновить сервис без этой ошибки? Мой обходной путь - вручную зайти в панель управления, удалить предыдущее приложение, а затем запустить установщик.
5 ответов
Помимо того, что StingyJack отметил, что версии файлов отличаются, у вас есть еще одна проблема. Из документации VS (извините, не онлайн)
Если вы установили и установите и удалите настраиваемые действия в проекте установки приложения и включили свойство RemovePreviousVersions в Visual Studio 2005, предыдущая версия продукта будет удалена во время обновления. Однако это поведение изменилось в Visual Studio 2008 следующим образом:
В Visual Studio 2005 настраиваемые действия вызывались следующим образом при обновлении с v1.0.0 до v1.0.1:
v1.0.0 настраиваемое действие Uninstall ()
v1.0.1 настраиваемое действие Install()
В Visual Studio 2008 действие удаления не вызывается, как показано ниже:
v1.0.1 настраиваемое действие Install()
Если вы создали настраиваемые действия, опираясь на старое поведение, вам необходимо изменить код для нового поведения. Это изменение поведения влияет только на обновления, но не на удаление.
Таким образом, вы устанавливаете службу, используя настраиваемое действие, но при обновлении часть удаления не вызывается так, как вы ожидаете, и вы пытаетесь установить поверх существующей работающей версии.
Я думаю, что когда он запрашивает перезагрузку, потому что он не может обновить файл служб во время его работы.
Два варианта:-
Добавьте код в настраиваемое действие Install/Commit для остановки службы, подождите, пока установщик заменит файлы служб, а затем перезапустите службу. Смотрите ответ PonalSuper3 в этой теме
Верните поведение VS2008 обратно к тому, как оно работало в VS2005 (настраиваемое действие удаления старых версий вызывается перед установкой новой версии) с помощью Orca, чтобы изменить InstallExecuteSequence.RemoveExistingProducts сразу после.InstallInitialize - обычно вы устанавливаете.RemoveExistingProducts равным 1525 но проверьте свой индивидуальный MSI.
Я добавил скрипт, который вы можете добавить в процесс сборки, чтобы изменить MSI InstallExecuteSequence
Поместите "Не (установлено или предварительно установлено в)" в свойстве Custom Actions->Install Condition.
Убедитесь, что версия сборки службы и GUID (в AssemblyInfo.vb/cs) изменяются при развертывании каждого нового пакета установщика. Если он обнаруживает ту же версию, обновления не удаются.
Что-то, что может помочь, но не было указано ни в одном из вышеперечисленных, что связано с ответом Райана. Такая же проблема случалась со мной, пока я не сделал это: откройте MSI-файл в Orca и найдите таблицу обновлений. Там, где предыдущая версия установлена (была первая запись в моей), вы должны увидеть код обновления. Найдите MSI программы, которая установлена в данный момент (ту, которую вы хотите обновить), найдите код обновления (который вы можете сделать в orca), скопируйте и вставьте его в эту таблицу обновлений для вашего нового MSI. Это помогло мне.
Попробуйте этот код в вашем классе установщика. Я надеюсь, что это решит вашу проблему.
protected override void OnBeforeInstall(IDictionary savedState)
{
if (LaunchOnBeforeInstall())
{
base.OnBeforeInstall(savedState);
}
else
{
throw new Exception("You cancelled installation");
}
}
public bool LaunchOnBeforeInstall()
{
Form2 frm2 = new Form2();
DialogResult result = frm2.ShowDialog();
if (result == DialogResult.Cancel)
{
return false;
}
else
{
return true;
}
}