visual-studio 当我安装新版本的软件时,如何消除“指定的服务已经存在”?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 
原文地址: http://stackoverflow.com/questions/451573/
Warning: these are provided under cc-by-sa 4.0 license.  You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I eliminate "The specified service already exists" when I install new versions of my software?
提问by pc1oad1etter
I have a VS2008 application that includes a service project (I'll call it ServiceProject). I have the installation project (InstallationProject) set to RemovePreviousVersions. Additionally, I have Custom Actions setfor InstallationProject, to Install, Commit, Rollback, and Uninstall the Primary output from ServiceProject.
我有一个 VS2008 应用程序,其中包含一个服务项目(我将其称为 ServiceProject)。我将安装项目 (InstallationProject) 设置为 RemovePreviousVersions。此外,我为 InstallationProject设置了自定义操作,以安装、提交、回滚和卸载 ServiceProject 的主要输出。
Sometimes when I build new versions of the installer, I can install without an error. Often, when I get to the point of setting up the service (entering a username and password into the installer) - it fails with the error, "The specified service already exists".
有时,当我构建新版本的安装程序时,我可以安装而不会出错。通常,当我开始设置服务(在安装程序中输入用户名和密码)时 - 它会失败并显示错误,“指定的服务已经存在”。
I don't know why it's inconsistent, though I've considered that maybe there is some kind of signature for the service and if the service is unmodified, it is able to remove it successfully, but with modifications, it doesn't recognize the service. However, I rarely make modifications to the service, so I doubt that's it.
我不知道为什么它不一致,尽管我考虑过该服务可能存在某种签名,如果该服务未修改,则可以成功删除它,但是经过修改,它无法识别服务。但是,我很少对服务进行修改,所以我怀疑就是这样。
How can I make my installer successfully update the service without this error?My work-around is to manually go into Control Panel, uninstall the former application, then run the installer.
如何让我的安装程序成功更新服务而不会出现此错误?我的解决方法是手动进入控制面板,卸载以前的应用程序,然后运行安装程序。
回答by Ryan
In addition to making sure the file versions are different as StingyHyman mentioned you have another problem. From the VS documentation (sorry, not online)
除了确保文件版本不同之外,StingyHyman 提到您还有另一个问题。来自 VS 文档(抱歉,不是在线的)
If you have set both install and uninstall custom actions in an application's setup project, and you have enabled the RemovePreviousVersions property in Visual Studio 2005, the previous version of the product is uninstalled during an upgrade. However, this behavior changed in Visual Studio 2008 as follows:
In Visual Studio 2005, the custom actions were called as follows on an upgrade from v1.0.0 to v1.0.1:
v1.0.0 custom action Uninstall()
v1.0.1 custom action Install()
In Visual Studio 2008, the uninstall action is not called, as follows:
v1.0.1 custom action Install()
If you created custom actions relying on the old behavior, you need to modify your code for the new behavior. This behavior change affects only updates, not uninstalls.
如果在应用程序的安装项目中设置了安装和卸载自定义操作,并且在 Visual Studio 2005 中启用了 RemovePreviousVersions 属性,则在升级过程中将卸载该产品的先前版本。但是,这种行为在 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()
如果您创建了依赖于旧行为的自定义操作,则需要针对新行为修改代码。此行为更改仅影响更新,而不影响卸载。
So you are installing a service using a custom action - but when upgrading the Uninstall part is not being called as you expect and you are trying to Install over an existing, running version.
因此,您正在使用自定义操作安装服务 - 但是在升级时未按预期调用卸载部分,并且您正在尝试通过现有的运行版本进行安装。
I thinkthat when its asking for a reboot is because it can't update the services file whilst its running.
我认为当它要求重新启动是因为它在运行时无法更新服务文件。
Two options :-
两种选择:-
Add code to your Install/Commit custom action to Stop the service, wait for the installer to replace the services files and then restart the service. See PonalSuper3's answer in this thread
将代码添加到您的安装/提交自定义操作以停止服务,等待安装程序替换服务文件,然后重新启动服务。在此线程中查看PonalSuper3 的回答
Put the VS2008 behaviour back to how it worked in VS2005(the old versions Uninstall custom action is called before the new version Install) by using Orca to alter the InstallExecuteSequence.RemoveExistingProducts to be immediately after .InstallInitialize - usually you set the .RemoveExistingProducts to 1525 but check your individual MSI.
通过使用 Orca 将 InstallExecuteSequence.RemoveExistingProducts 更改为紧跟在 .InstallInitialize 之后,将 VS2008 行为恢复到它在 VS2005 中的工作方式(旧版本卸载自定义操作在新版本安装之前调用) - 通常您将 .RemoveExistingProducts 设置为 1525但请检查您的个人 MSI。
I've added a script than you can add to your build process to change the MSI's InstallExecuteSequence
回答by Tomer Pintel
Put "Not (Installed OR PREVIOUSVERSIONSINSTALLED)" in the Custom Actions->Install Condition property.
将“Not (Installed OR PREVIOUSVERSIONSINSTALLED)”放在自定义操作->安装条件属性中。
回答by StingyHyman
Make sure that the assembly version of the service and the GUID (In AssemblyInfo.vb/cs) are getting changed when you deploy each new installer package. If it detects the same version then updates fail.
确保在部署每个新的安装程序包时服务的程序集版本和 GUID(在 AssemblyInfo.vb/cs 中)正在更改。如果它检测到相同的版本,则更新失败。
回答by GetBrutal
Something that may help but was not stated in any of the above that is related to Ryan's answer. This same problem happened to me until I did this: open the .msi in Orca and locate the Upgrade table. Where the previousversioninstalled line (was the first entry in mine) is, you should see an upgrade code. Find the .msi of the program that is currently installed (the one you want to upgrade), find the upgrade code (which you can do in orca), and copy and paste it into that upgrade table for your new .msi. This did the trick for me.
与瑞安的回答相关的任何可能有帮助但未在上述任何内容中说明的内容。同样的问题也发生在我身上,直到我这样做:在 Orca 中打开 .msi 并找到升级表。previousversioninstalled 行(是我的第一个条目)所在的位置,您应该会看到升级代码。找到当前安装的程序的 .msi(您要升级的那个),找到升级代码(您可以在 orca 中执行),然后将其复制并粘贴到新 .msi 的升级表中。这对我有用。
回答by Tanmay Nehete
Try this code in your installer class. I hope it will resolve your problem.
在您的安装程序类中试试这个代码。我希望它能解决你的问题。
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;
            }
        }


