51

SC.exe and InstallUtil both install/uninstall windows services. But they don't seem to work the same way.

What is the difference?


For instance InstallUtil fails (some file or dependency not found error) while Sc create happily installs the service. Too add to the strangeness; the service doesn't show up if I run net start in the console. But it does show up in the services GUI. Variants of this happen when I try to uninstall.

I have written the service myself and earlier versions work. Dotnet3.5.

LosManos
  • 7,195
  • 6
  • 56
  • 107
  • 1
    Here is a caveat: uninstallation (can't remember if it is sc.ex or installUtil) isn't possible if you have the services open in the control panel. – LosManos Feb 19 '12 at 15:29
  • Maybe the OP meet the same error with me: when using InstallUtil, I tried to configure the service name in App.config. It turns out that we can't install the service if we read from the config file (must be a dependency thing). In the end we decide to hardcode the service name. Then switch to SC – Hoàng Long May 26 '16 at 01:51

5 Answers5

29

Yes, installing a service isn't particularly complicated. It just takes writing a handful of registry keys. You can have a look-see with Regedit.exe, navigate to HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services.

Sc.exe can write these keys too, using the supplied command line arguments. Nevertheless, this is not the right way to do it. The point of InstallUtil.exe is that it can activate custom installation code. Code that the service author wrote. Which is not that uncommon, services tend to stuff config info in their registration keys for their own use. You'll see plenty of evidence for that when you have a look with Regedit.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • 4
    In particular, sc.exe does not create the required entries for the Windows EventLog, which .NET bases services typically use. – Christian.K Jan 17 '11 at 08:11
  • I believe we can always write whatever custom code we need inside the service itself? Doing some projects till now, I still not see what InstallUtil can do but SC cannot do. For Windows Event Log, we can create ourselves if it is necessary (we don't use much Event Log though). Maybe SC improve since last time? – Hoàng Long May 26 '16 at 02:01
  • 2
    It can find .NET code with the [Installer] attribute and execute it. SC.exe cannot do that. This is the way Microsoft documented it, you don't have to do it this way. – Hans Passant May 26 '16 at 04:47
  • 1
    Why not create the event log inside the service? Because the service usually run with less permissions than you have during installtion – Assaf S. Sep 21 '16 at 14:02
17

I prefer sc.exe over installutil.exe.

InstallUtil forces you to add the dreadful ProjectInstaller class (I believe) and hardcode there the service name and service description.

InstallUtil makes it very hard to put two versions of the same service running in the same machine at the same time.

That's why I just don't use InstallUtil.exe at all. Also because of previous responses: you need it to be in your deploy package. sc.exe is already in any Windows Xp and above (I believe).

Kat Lim Ruiz
  • 2,425
  • 2
  • 26
  • 32
  • 5
    This is not true, you don't need to hardcode the service name. With some extra few lines of code you provide the name for the service when installing it with installutil – furier Nov 01 '13 at 11:09
  • I didnt know that, though I never gave it much thought. Thanks for the info – Kat Lim Ruiz Nov 01 '13 at 22:23
  • 1
    @furier - I know this is an old comment, but can you show how you provide the name for the service? – Jeremy Sep 21 '15 at 16:53
  • put in command prompt: sc create help, it will tell you the syntax, there is DisplayName – Kat Lim Ruiz Sep 21 '15 at 17:09
  • How would one deploy a windows service on a remote host using sc.exe? How would one do automatic deployment of a WS using sc.exe and no installer class? – AlexandruC Feb 18 '16 at 12:28
  • @AlexandruC. : a simple bat script would take care of that. – Hoàng Long May 26 '16 at 01:45
  • @furier: I don't know how, but if I tried to read the service name from App.config, the service always fail to install. Looks like we can read from App.config before the service itself start... really tricky – Hoàng Long May 26 '16 at 01:46
  • @AlexandruC.: sc already has a syntax to apply the command to remote host. Something along sc //myhost ... I think you need some kind of permission on your remote host to do it though – Kat Lim Ruiz May 26 '16 at 20:27
  • also to add to this idea, i've used the sc //myremotehost basically to have a central deploy machine from which I push my app to different hosts. – Kat Lim Ruiz Oct 21 '16 at 16:47
  • @Wjdavis5 hi, can I understand why it is incorrect? – Kat Lim Ruiz Feb 16 '18 at 18:57
  • Bc with install util you can easily define the service name and display name in the app.config. Allowing you to easily install multiple instances – Wjdavis5 Feb 16 '18 at 21:48
  • thats another way to look at it. But that doesnt mean mine is incorrect! ha ha. – Kat Lim Ruiz Feb 20 '18 at 20:25
  • What? You said "and hardcode there the service name and service description." That is wrong - you do not have to do this at all. – Wjdavis5 Feb 22 '18 at 11:48
  • @HoàngLong You can't use app.config the way you usually do, because it's not your process that's running - it's InstallUtil's. If you need data from app.config, you need to read it manually (not as hard as it may sound), otherwise you just get data from InstallUtil's configs. – Luaan Aug 28 '18 at 14:05
  • Thanks @Luaan for the information. I just wish Microsoft has a clearer error message about what happened, NOT failed silently. My silly wish :( – Hoàng Long Aug 28 '18 at 16:20
  • @HoàngLong That's tricky, because that is the standard behaviour. After all, running code from SomeLibrary.dll isn't going to load its configuration from SomeLibrary.dll - it's still YourApp.exe.config. The runtime doesn't know you *wanted* to load a different config. Though certainly it seems that InstallUtil itself swallows some exceptions which makes debugging tricky and would be a great thing to improve :) Then again, you'd probably get something like a NullReferenceException anyway - better than nothing, but not by a whole lot. – Luaan Aug 28 '18 at 17:20
5

Main difference is that InstallUtil is not utility meant for service installation but as general installer tool. From MSDN pages you can see that:

"The Installer tool is a command-line utility that allows you to install and uninstall server resources by executing the installer components in specified assemblies. This tool works in conjunction with classes in the System.Configuration.Install namespace."

So it can install service but it has many many many other benefits. Creating executables based on Installer Class gives you programatic control of whole installation/uninstallation procedure. ServiceInstaller and ServiceProcessInstaller, for instance, are used for service installation.

'Sc' utility is used for service control and 'create' command will just create service based on chosen executable.

In your example
1. It is not meant to be installed with InstallUtil and error response should be quite clear about it.
2. InstallUtil fails because of a bug in installation code and using sc create will probably create a faulty service for you. Check into {exe_name}.InstallLog for details.

Bizniztime
  • 1,016
  • 10
  • 22
  • sc will also create the log – Hoàng Long May 26 '16 at 01:50
  • @HoàngLong are you sure about that? what is the name of the log file? – Bizniztime Jun 03 '16 at 13:25
  • the log file is [Filename].InstallLog and [Filename].InstallState (). The InstallLog contains things like "Installing assembly... Affected parameters are..." The InstallState is a XML file. I'm very sure because I did it on our server before (maybe it change since you write the answer). – Hoàng Long Jun 06 '16 at 01:51
  • 1
    @HoàngLong Those are created by InstallUtil not sc – Bizniztime Jun 13 '16 at 08:08
  • just double-checked again. Turns out one of my services produces the log, the other doesn't (both use SC). Strange. Double-check everything, it seems both services are similar. The only difference I see is that one requires an account with username/password to set up while the other does not (Account = ServiceAccount.User vs. Account = ServiceAccount.LocalSystem) – Hoàng Long Jun 13 '16 at 08:51
  • @HoàngLong Services don't use SC. You use SC to control services from command prompt. As for the log read this article about InstallUtil and you will see that those files where created by that utility. (Remarks section) https://msdn.microsoft.com/en-us/library/50614e95(v=vs.110).aspx – Bizniztime Jun 14 '16 at 09:44
  • yes, SC was used to control service in the case I mentioned. I checked the article, this is interesting: "You can use an assembly's installer components to create these resources... Installutil.exe detects and executes these installer components" So in my case, look like SC does "detect and execute" these write-log-components when some conditions are fulfilled. Though I'd give in to you that InstallUtil would always create these logs. – Hoàng Long Jun 15 '16 at 01:37
3

While InstallUtil is the preferred way to go with .NET services, one of it's shortcomings is it won't pick up binding redirects from your app.config, which in certain circumstances, can cause the install to fail. That's where using SC might gain you some benefit, at the expense of not being able to run code at install time.

Unfortunately for the OP, TopShelf didn't exist at the time of his question. It works around the shortcomings of both SC and InstallUtil, and allows the service to start up with the debugger attached when starting it in Visual Studio. Plus, it's a lot easier to type myservice install than have to drill down to the specific folder for InstallUtil, or type in a ton of parameters for SC.

Joe the Coder
  • 1,775
  • 1
  • 19
  • 22
2

From the uninstall usage experience: sc.exe under windows 7 removes the entry from the list immediately, while after uninstalling with installutil there is a need for restart

Cyryl Płotnicki
  • 473
  • 6
  • 12