Installing Services

  • Thread starter Thread starter Waldy
  • Start date Start date
W

Waldy

Hi there,
in the past when we have written services with C++, we used
to install them by running the .exe with command line parameters for
install/uninstall. Is this still possible with .Net? If this is not
possible, do I need to take the InstallUtil.exe with me to install on
customer site, or can I create a deployment package to do this for me?

Thanks.
 
Well, I use the InstallUtil.exe

Install: C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\installutil
yourService.exe
Uninstall: C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\installutil /u
yourService.exe
 
Yes, it's possible:

public void DoInstall(bool install)
{
// install or uninstall the service
using (TransactedInstaller ti = new TransactedInstaller())
{
using (Installer inst = CreateInstaller())
{
ti.Installers.Add(inst);
string path = "/assemblypath=" + Assembly.GetEntryAssembly().Location;
InstallContext ctx = new InstallContext(@"C:\install.log", new string[]
{ path });
ti.Context = ctx;

if (install)
{
Hashtable dict = new Hashtable();

try
{
ti.Install(dict);
}
catch (Exception e)
{
ti.Uninstall(null);
throw;
}
}
else
{
ti.Uninstall(null);
}
ti.Installers.Remove(inst);
}
}

May contain errors, this is a snippet from my own code.

HTH,
Stefan
 
Hi,

No, you can but you don't have to

The best way to install a win service is including a Installer in the
project ( right click on the project name in the project explorer) and add a
Setup project to the solution, add a custom action consisting of the primary
output of the win service and you are really to go.

Ps : I have a link somewhere from MSDN for this approach I will look for it
in case you need further help

cheers,
 
Stefan Simek said:
Yes, it's possible:

public void DoInstall(bool install)
{
// install or uninstall the service
using (TransactedInstaller ti = new TransactedInstaller())
{
using (Installer inst = CreateInstaller())
{
ti.Installers.Add(inst);
string path = "/assemblypath=" + Assembly.GetEntryAssembly().Location;
InstallContext ctx = new InstallContext(@"C:\install.log", new string[]
{ path });
ti.Context = ctx;

if (install)
{
Hashtable dict = new Hashtable();

try
{
ti.Install(dict);
}
catch (Exception e)
{
ti.Uninstall(null);
throw;
}
}
else
{
ti.Uninstall(null);
}
ti.Installers.Remove(inst);
}
}

May contain errors, this is a snippet from my own code.

HTH,
Stefan

Hi Stefan,
the CreateInstaller() call does not appear to be part of
..Net. What code is in this function?

Thanks.
 
Stefan,
how did you get hold of the command line parameters as no args
are passed into main?
 
Waldy said:
Stefan Simek said:
Yes, it's possible:

public void DoInstall(bool install)
{
// install or uninstall the service
using (TransactedInstaller ti = new TransactedInstaller())
{
using (Installer inst = CreateInstaller())
{
ti.Installers.Add(inst);
string path = "/assemblypath=" + Assembly.GetEntryAssembly().Location;
InstallContext ctx = new InstallContext(@"C:\install.log", new
string[]
{ path });
ti.Context = ctx;

if (install)
{
Hashtable dict = new Hashtable();

try
{
ti.Install(dict);
}
catch (Exception e)
{
ti.Uninstall(null);
throw;
}
}
else
{
ti.Uninstall(null);
}
ti.Installers.Remove(inst);
}
}

May contain errors, this is a snippet from my own code.

HTH,
Stefan

Hi Stefan,
the CreateInstaller() call does not appear to be part of
.Net. What code is in this function?

Thanks.

Sorry, my fault... I just cut the previous snippet out, I didn't realize it
calls another...

The CreateInstaller() goes as follows, hope it should be complete now.

Installer CreateInstaller()
{
Installer inst = new Installer();

ServiceProcessInstaller spi = new ServiceProcessInstaller();
spi.Account = account;

ServiceInstaller si = new ServiceInstaller();
si.DisplayName = name;
si.ServiceName = name;
si.StartType = startMode;

inst.Installers.AddRange(new Installer[] { spi, si });

return inst;
}

HTH,
Stefan
 
Waldy said:
Stefan,
how did you get hold of the command line parameters as no args
are passed into main?

What do you mean by: no args are passed into main?

If you need the arguments, declare your main function as:

public static void Main(string[] args)
{
...
}

If you need to retrieve the arguments somewhere else in your code, you can
use Environment.GetCommandLineArgs(), but beware, this also returns
executable name as the first element of the array, so it's not directly
interchangeable with the args passed to main...

HTH,
Stefan
 
Back
Top