So we've produced a windows service to feed data to our client application and everything is going great. The client has come up with a fun configuration request that requires two instances of this service running on the same server and configured to point at separate databases.
So far I haven't been able to get this to happen and was hoping my fellow stackoverflow members might be able to give some hints as to why.
Current setup:
I've set up the project that contains the windows service, we'll call it AppService from now on, and the ProjectInstaller.cs file that handles custom installation steps to set the service name based on a key in the App.config like so:
this.serviceInstaller1.ServiceName = Util.ServiceName;
this.serviceInstaller1.DisplayName = Util.ServiceName;
this.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalSystem;
In this case Util is just a static class tha tloads the service name from the config file.
From here forward I have tried two different ways to get both services installed and both have failed in an identical way.
The first way was to simply install the first copy of the service, copy the installed directory and renamed it, and then ran the following command after modifying the app config to change the desired service name:
InstallUtil.exe /i AppService.exe
When that didn't work I tried to create a second installer project, edited the config file and built the second installer. When I ran the installer it worked fine but the service did not show up in services.msc so I ran the previous command against the second installed code base.
Both times i received the following output from InstallUtil (relevant parts only):
Running a transacted installation.
Beginning the Install phase of the installation.
Installing service App Service Two... Service App Service Two has been successfully installed. Creating EventLog source App Service Two in log Application...
An exception occurred during the Install phase. System.NullReferenceException: Object reference not set to an instance of an object.
The Rollback phase of the installation is beginning.
Restoring event log to previous state for source App Service Two. Service App Service Two is being removed from the system... Service App Service Two was successfully removed from the system.
The Rollback phase completed successfully.
The transacted install has completed. The installation failed, and the rollback has been performed.
Sorry for the long winded post, wanted to make sure there is enough relevant information. The piece that so far has me stumped is that it states that the installation of the service completes successfully and its only after it goes to create the EventLog source that the NullReferenceException seems to get thrown. So if anyone knows what I'm doing wrong or has a better approach it would be much appreciated.
Old question, I know, but I've had luck using the /servicename option on InstallUtil.exe. I don't see it listed in the built-in help though.
I'm not entirely sure where I first read about this but I haven't seen it since. YMMV.
Have you tried the sc / service controller util? Type
at a command line, and it will give you the help entry. I think I've done this in the past for Subversion and used this article as a reference:
http://svn.apache.org/repos/asf/subversion/trunk/notes/windows-service.txt
The simplest approach is is based the service name on the dll name:
Another quick way to specify a custom value for
ServiceName
andDisplayName
is usinginstallutil
command line parameters.In your
ProjectInstaller
class override virtual methodsInstall(IDictionary stateSaver)
andUninstall(IDictionary savedState)
Install the service with
installutil
adding your custom name using/servicename
parameter:Please note that if you do not specify
/servicename
in the command line the service will be installed with ServiceName and DisplayName values specified in ProjectInstaller properties/configI didn't have much luck with the above methods when using our automated deployment software to frequently install/uninstall side-by-side windows services, but I eventually came up with the following which allows me to pass in a parameter to specify a suffix to the service name on the command line. It also allows the designer to function properly and could easily be adapted to override the entire name if necessary.
With this in mind, I can do the following: If I've called the service "Awesome Service" then I can install a UAT verison of the service as follows:
InstallUtil.exe /ServiceSuffix="UAT" MyService.exe
This will create the service with the name "Awesome Service - UAT". We've used this to run DEVINT, TESTING and ACCEPTANCE versions of the same service running side-by-side on a single machine. Each version has its own set of files/configs - I haven't tried this to install multiple services pointing at the same set of files.
NOTE: you have to use the same
/ServiceSuffix
parameter to uninstall the service, so you'd execute the following to uninstall:InstallUtil.exe /u /ServiceSuffix="UAT" MyService.exe
I had a similar situation, where i to needed have a previous service, and an updated service running side by side on the same server. (It was more than just a database change, it was code changes as well). So I couldn't just run the same .exe twice. I needed a new .exe that was compiled with new DLLs but from the same project. Just changing the service name and display name of the service did not work for me, I still received the "service already existed error" which I believe is because I am using a Deployment Project. What finally did work for me is within my Deployment Project Properties there is a property called "ProductCode" which is a Guid.
After that, rebuilding the Setup Project to a new .exe or .msi installed successfully.