Installing a .NET Windows Service using InstallUtil

R

Randy

Hello,
I created a Windows Service (c#) and finally deciphered how to add an
Installer to the project. I got all this to work. On my machine I can
install/remove the service by using...
InstallUtil JTEService.exe
and InstallUtil /u JTEService.exe

I tried to install it on another machine with .NET Framework on this other
machine and it won't install. In the install log file it says...

No public installers with the RunInstallerAttribute.Yes attribute could be
found

Does anyone know what I must do at this point to install the service on this
other machine? I thought if the framework was on it all I'd have to do is
use InstallUtil...

Thanks

Cheers :)
 
J

Joe Delekto

Greets,

I wrote the following document which may help you create an installing
service step-by-step using Visual Studio.NET:


I. Overview



In order to simplify deployment for service applications that are developed
with Microsoft .NET and Visual Studio 2002/2003, components are provided
that can be used to set up the registry keys and perform the installation
time registration of the .NET service.



These instructions assume a simple project that consists of one service
application and the actual installation project that will be used to install
the service.



II. Creating the Solution



To create the solution, use "File." "New." and select "Blank Solution." from
the Visual Studio development environment. For this example, call the
solution "ServiceSolution".



All related projects (especially those that will be part of an installation,
should become a project within the root solution. This keeps all
inter-project dependencies relative to one another and simplifies the
process if another developer decides to use a working folder.



The next step is to create two new projects as part of this solution: the
service application and the installation package. Right click on the
solution within the Solution Explorer and select "Add." and then "New
Project." from the Visual C# projects folder, choose "Windows Service".
Name the project "TestService". The resulting project should now be in
design mode and ready to add the installation components.



The C# source file "Service1" and the class name "Service1" are added to the
project; replace all occurrences of "Service1" with "TestService", including
the string used to name the service in the InitializeComponent() method.



In the design view, right click and select "Add Installer" from the context
menu. A new source file "ProjectInstaller.cs" with the class named
"ProjectInstaller" will be added to the project. Two components will also be
added to your project with the default names "serviceInstaller1" and
"serviceProcessInstaller1". These components use the .NET framework to
handle the registry key setup and installation of the service. You can opt
to change the names of these components, but for this example keep them the
same.



III. Service Properties



In the design view, you can select the "serviceProcessInstaller1" component
and modify its properties. For the "account" property, you can choose the
type of account this service will use. For a user account, a name and
password can be supplied in the code, but this should not be done. For
production services, the service type should typically be user and then the
name and password set to 'null'. At installation time, the production
support personnel will be prompted to enter the name and password for the
account under which the service will run. Be sure to specify what resources
will be required by the application so that the account's permissions may be
set appropriately.



Next, select the "serviceInstaller1" component in the design view. In the
properties window, the name property should be set to "TestService" which is
the name of the class we chose for our service. You only need to change
this property if you want the Service Control Manager to recognize your
service with a different name.



In the "ServicesDependedOn" property, add the service name (as shown in the
Service Control Manager) of any other dependent services that your service
requires. This can be other services such as Microsoft Message Queuing,
IIS, etc.



For the "DisplayName" property, choose a short friendly name that is
displayed when the services are listed in the control panel. For our
service, we'll use "Test Service" (with a space).



IV. Adding a Description



You'll note that there is no description property available for the service
through any of the components. In order to add a useful description to the
service that can be read by anyone, some code will need to be added to the
"ProjectInstaller" class that was created.



We'll want to add a registry key under the same location where the other
service properties are kept. To do this, we will override the virtual
Install() method, call the base class Install() in order to create the root
registry keys, then add our new key with the description.



public override void Install(IDictionary mySavedState)

{

// call the original Install() method to create root key

base.Install(mySavedState);



Microsoft.Win32.RegistryKey ServiceDescription = null;

try

{

ServiceDescription =
Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"System\CurrentControlSet\
Services\" + ServiceInstaller1.ServiceName, true);

ServiceDescription.SetValue("Description", "This is our test service
description.");

ServiceDescription.Close();

}

catch(Exception)

{

}

}



Note that we don't need to worry about any other overrides to remove the
key. When the root key is removed by the service installer base class, the
new "Description" key will be removed as well since it is a child of that
key.



Note also that the name property was used to create the service name. This
is to avoid hard-coding the name should it ever change and ensures we create
the correct key name based on the service name.



The service is now ready to be developed in accordance to the service
specification; prior to development, however, we can create the installation
package along with the custom steps required to install the product.



V. MSI Package Setup



The final step of the exercise is to create the MSI installation package
that will be used to install our test service. From the Solution Explorer,
right click on the "ServiceSolution" and choose "Add." then "New Project."
from the context menu. From the "Setup and Deployment Projects" folder,
select "Setup Project" and then name it TestServiceInstall".



Instead of focusing on the various properties for the installation, instead
we will just go through the steps required to install the service
application and then execute the service installation components that will
occur when the MSI is deployed.



With the "TestServiceInstall" project selected in the Solution Explorer, you
should see icons appear over the project folders. Select the first icon
which is the "File System" installation folders. Right click on the
"Application Folder" in the project pane and select "Add." and "Project
Output." from the context menus.



Make sure that the "TestService" project is selected in the project
drop-down and then click on "Primary Output" in the list box. Keep the
"Configuration" dropdown to "(Active)". This will allow the installation
project to use the appropriate output for either a debug or release build
depending upon which you choose to create for the installation. (Debug
builds are useful for development/stage environment deployment in some
testing situations.)



The fifth icon on the top is the "Custom Actions" editor. Custom actions
can be callbacks in code (in this case, they are part of the
"ProcessInstaller" class that was created for us. We need to associate the
"primary" output of our application to each of the custom installation
steps.



To do this in one fell swoop, click the "Custom Actions" icon to show the
actions view. There are several folders with the names "Install", "Commit",
"Rollback" and "Uninstall". Right click on the top level "Custom Actions"
node and select "Custom Action."



In the next dialog, open the dropdown and select "Application Folder". You
should now see the "Primary output from TestService (Active)" in the list
view, as this is where we added our project's output. Select this item in
the list and choose "OK". The primary output for the service will now be
associated with all of the custom actions and the service installer classes
that were added to the project will now be called to perform the various
installation steps when the MSI package is deployed.



VI. Testing



We are now ready to create the installation package and see the results of
the service installation. Right click on the "TestServiceInstall" project
and choose "Build" from the context menu.



When the "TestServiceInstall.msi" file is created, navigate to the output
folder where it was placed and double click on it to perform the
installation. The other installation properties (such as the splash screen
display name, copyright information, other dependencies, etc.) can be added
as needed as this is only a test project.



When installing, choose "Everyone" for the installation and continue to
click next. You will eventually be prompted with the dialog to enter your
login name and credentials. You can use your network logon for testing
purposes. When installation is complete, use the Administrative Tools to
view the installed service applications. You should see the "Test Service"
along with its description and the credentials used by the service
application.



After closing the services window, use the "Add/Remove Programs"
functionality from the Control Panel to uninstall the service and it should
no longer appear in list of available services.



Regards,



Joe
 
R

Randy

Thanks for the info Joe :)

Joe Delekto said:
Greets,

I wrote the following document which may help you create an installing
service step-by-step using Visual Studio.NET:


I. Overview



In order to simplify deployment for service applications that are developed
with Microsoft .NET and Visual Studio 2002/2003, components are provided
that can be used to set up the registry keys and perform the installation
time registration of the .NET service.



These instructions assume a simple project that consists of one service
application and the actual installation project that will be used to install
the service.



II. Creating the Solution



To create the solution, use "File." "New." and select "Blank Solution." from
the Visual Studio development environment. For this example, call the
solution "ServiceSolution".



All related projects (especially those that will be part of an installation,
should become a project within the root solution. This keeps all
inter-project dependencies relative to one another and simplifies the
process if another developer decides to use a working folder.



The next step is to create two new projects as part of this solution: the
service application and the installation package. Right click on the
solution within the Solution Explorer and select "Add." and then "New
Project." from the Visual C# projects folder, choose "Windows Service".
Name the project "TestService". The resulting project should now be in
design mode and ready to add the installation components.



The C# source file "Service1" and the class name "Service1" are added to the
project; replace all occurrences of "Service1" with "TestService", including
the string used to name the service in the InitializeComponent() method.



In the design view, right click and select "Add Installer" from the context
menu. A new source file "ProjectInstaller.cs" with the class named
"ProjectInstaller" will be added to the project. Two components will also be
added to your project with the default names "serviceInstaller1" and
"serviceProcessInstaller1". These components use the .NET framework to
handle the registry key setup and installation of the service. You can opt
to change the names of these components, but for this example keep them the
same.



III. Service Properties



In the design view, you can select the "serviceProcessInstaller1" component
and modify its properties. For the "account" property, you can choose the
type of account this service will use. For a user account, a name and
password can be supplied in the code, but this should not be done. For
production services, the service type should typically be user and then the
name and password set to 'null'. At installation time, the production
support personnel will be prompted to enter the name and password for the
account under which the service will run. Be sure to specify what resources
will be required by the application so that the account's permissions may be
set appropriately.



Next, select the "serviceInstaller1" component in the design view. In the
properties window, the name property should be set to "TestService" which is
the name of the class we chose for our service. You only need to change
this property if you want the Service Control Manager to recognize your
service with a different name.



In the "ServicesDependedOn" property, add the service name (as shown in the
Service Control Manager) of any other dependent services that your service
requires. This can be other services such as Microsoft Message Queuing,
IIS, etc.



For the "DisplayName" property, choose a short friendly name that is
displayed when the services are listed in the control panel. For our
service, we'll use "Test Service" (with a space).



IV. Adding a Description



You'll note that there is no description property available for the service
through any of the components. In order to add a useful description to the
service that can be read by anyone, some code will need to be added to the
"ProjectInstaller" class that was created.



We'll want to add a registry key under the same location where the other
service properties are kept. To do this, we will override the virtual
Install() method, call the base class Install() in order to create the root
registry keys, then add our new key with the description.



public override void Install(IDictionary mySavedState)

{

// call the original Install() method to create root key

base.Install(mySavedState);



Microsoft.Win32.RegistryKey ServiceDescription = null;

try

{

ServiceDescription =
Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"System\CurrentControlSet\
Services\" + ServiceInstaller1.ServiceName, true);

ServiceDescription.SetValue("Description", "This is our test service
description.");

ServiceDescription.Close();

}

catch(Exception)

{

}

}



Note that we don't need to worry about any other overrides to remove the
key. When the root key is removed by the service installer base class, the
new "Description" key will be removed as well since it is a child of that
key.



Note also that the name property was used to create the service name. This
is to avoid hard-coding the name should it ever change and ensures we create
the correct key name based on the service name.



The service is now ready to be developed in accordance to the service
specification; prior to development, however, we can create the installation
package along with the custom steps required to install the product.



V. MSI Package Setup



The final step of the exercise is to create the MSI installation package
that will be used to install our test service. From the Solution Explorer,
right click on the "ServiceSolution" and choose "Add." then "New Project."
from the context menu. From the "Setup and Deployment Projects" folder,
select "Setup Project" and then name it TestServiceInstall".



Instead of focusing on the various properties for the installation, instead
we will just go through the steps required to install the service
application and then execute the service installation components that will
occur when the MSI is deployed.



With the "TestServiceInstall" project selected in the Solution Explorer, you
should see icons appear over the project folders. Select the first icon
which is the "File System" installation folders. Right click on the
"Application Folder" in the project pane and select "Add." and "Project
Output." from the context menus.



Make sure that the "TestService" project is selected in the project
drop-down and then click on "Primary Output" in the list box. Keep the
"Configuration" dropdown to "(Active)". This will allow the installation
project to use the appropriate output for either a debug or release build
depending upon which you choose to create for the installation. (Debug
builds are useful for development/stage environment deployment in some
testing situations.)



The fifth icon on the top is the "Custom Actions" editor. Custom actions
can be callbacks in code (in this case, they are part of the
"ProcessInstaller" class that was created for us. We need to associate the
"primary" output of our application to each of the custom installation
steps.



To do this in one fell swoop, click the "Custom Actions" icon to show the
actions view. There are several folders with the names "Install", "Commit",
"Rollback" and "Uninstall". Right click on the top level "Custom Actions"
node and select "Custom Action."



In the next dialog, open the dropdown and select "Application Folder". You
should now see the "Primary output from TestService (Active)" in the list
view, as this is where we added our project's output. Select this item in
the list and choose "OK". The primary output for the service will now be
associated with all of the custom actions and the service installer classes
that were added to the project will now be called to perform the various
installation steps when the MSI package is deployed.



VI. Testing



We are now ready to create the installation package and see the results of
the service installation. Right click on the "TestServiceInstall" project
and choose "Build" from the context menu.



When the "TestServiceInstall.msi" file is created, navigate to the output
folder where it was placed and double click on it to perform the
installation. The other installation properties (such as the splash screen
display name, copyright information, other dependencies, etc.) can be added
as needed as this is only a test project.



When installing, choose "Everyone" for the installation and continue to
click next. You will eventually be prompted with the dialog to enter your
login name and credentials. You can use your network logon for testing
purposes. When installation is complete, use the Administrative Tools to
view the installed service applications. You should see the "Test Service"
along with its description and the credentials used by the service
application.



After closing the services window, use the "Add/Remove Programs"
functionality from the Control Panel to uninstall the service and it should
no longer appear in list of available services.



Regards,



Joe
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top