Windows Service Help

D

dm3281

I'm really starting to hate writing services -- or trying to, anyway.

Why do I need to rename my project to the service name?

Why do I need to set the "ServiceName" property to my service name?

Why do I need to set a property within my code to the service name?

Are all these required or am I just doing this for consistency purposes?

Now for my real question/problem:

I have written this service and have this in my "SimpeService.cs":

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.ServiceProcess;
using System.Text;

namespace WindowsService2
{
public partial class SimpleService : System.ServiceProcess.ServiceBase
{
private System.Timers.Timer timer;

/// <summary>
/// Required deisgner variable
/// </summary>


public SimpleService()
{
// This call is required by the Windows.Forms Component Designer
InitializeComponent();

this.timer = new System.Timers.Timer();
this.timer.Enabled = true;
timer.Interval = 5000;
timer.Elapsed += new
System.Timers.ElapsedEventHandler(timer_Elapsed);
CanPauseAndContinue = true;
this.ServiceName = "Hello-World Service";

}

void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
EventLog.WriteEntry("Hello World!");
//throw new Exception("The method or operation is not
implemented.");
}

protected override void OnStart(string[] args)
{
// TODO: Add code here to start your service.
EventLog.WriteEntry("Hello-World Service Started");
timer.Enabled = true;
}

protected override void OnStop()
{
// TODO: Add code here to perform any tear-down necessary to
stop your service.
EventLog.WriteEntry("Hello-World Service Paused");
timer.Enabled = false;
}

protected override void OnPause()
{
EventLog.WriteEntry("Hello-World Service paused");
timer.Enabled = false;
}

protected override void OnContinue()
{
EventLog.WriteEntry("Hello-World Service continued");
timer.Enabled = true;
}

}
}


This is in my "ProjectInstaller.cs" and I have set the service properties,
etc:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration.Install;
using System.ServiceProcess;

namespace WindowsService2
{
[RunInstaller(true)]
public partial class ProjectInstaller : Installer
{
private ServiceInstaller serviceInstaller;
private ServiceProcessInstaller processInstaller;

public ProjectInstaller()
{
InitializeComponent();

processInstaller = new ServiceProcessInstaller();
serviceInstaller = new ServiceInstaller();

// Service will run under system account
processInstaller.Account = ServiceAccount.LocalSystem;

// Service will have Start Type of Manual
serviceInstaller.StartType = ServiceStartMode.Manual;
serviceInstaller.ServiceName = "Hello-World Service";
Installers.Add(serviceInstaller);
Installers.Add(processInstaller);
}
}
}

My "Program.cs" has no changes:

using System.Collections.Generic;
using System.ServiceProcess;
using System.Text;

namespace WindowsService2
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
ServiceBase[] ServicesToRun;

// More than one user Service may run within the same process.
To add
// another service to this process, change the following line to
// create a second service object. For example,
//
// ServicesToRun = new ServiceBase[] {new Service1(), new
MySecondUserService()};
//
ServicesToRun = new ServiceBase[] { new SimpleService() };

ServiceBase.Run(ServicesToRun);
}
}
}

Now, when I compiel the above, it all compiles fine.

I then jump to Admin Command Prompt and do a "installutil
WindowsService2.exe" and it does the following:

It pops up a dialoge asking me for service credentials. I'm not sure why
because I've defined them within my "ProjectInstaller.cs". But I was
getting this prior to setting any properties under the "ProjectInstaller.cs"
file. Why do I get this?

The format of the credentials appears to only accept "machinename\username"
and nothing else. It took me a while to figure this out! Arrghhh

After the service is installed, I appear to have two services:

SimpleService2
Hello-World

SimpleService2 won't start.
Hello-World starts and appears to work as expected. I can pause, etc.
without issue and items are appearing in event log.

Executing "InstallUtil -u WindowsService2.exe" appears to get rid of both
services.

I assume SimpleService2 is appearing because that is the name that I use
within the "SimpleService.cs" file??

I assume the crendtial dialogue is coming from this service and not
Hello-World because it appears to have the correct credentials.

How do I get rid of the dialoge all together?

How do I get rid of "SimpleService" installation, since it appears to not
work anyway.

Any help would be appreciated.
 
D

dm3281

All --

I think I made a bit of progress since this post. It would appear the the
"ProjectInstallerDesigner.cs" file has some of the same options that I was
setting; which had default options of null, etc. Remarking this out and
putting the other values in appeared to elimiante two services from being
installed. I'm not sure where I should put my changes. I was under the
impression that I wasn't suppose to modifiy the "Designer" classes.

Here is what is in "ProjectInstallerDesigner.cs"

namespace WindowsService2
{
partial class ProjectInstaller
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;

/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be
disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}

#region Component Designer generated code

/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.serviceProcessInstaller1 = new
System.ServiceProcess.ServiceProcessInstaller();
this.serviceInstaller1 = new
System.ServiceProcess.ServiceInstaller();
//
// serviceProcessInstaller1
//
//this.serviceProcessInstaller1.Password = null;
//this.serviceProcessInstaller1.Username = null;
this.serviceProcessInstaller1.Account =
System.ServiceProcess.ServiceAccount.LocalSystem;
//
// serviceInstaller1
//
this.serviceInstaller1.ServiceName = "Hello-World2";
this.serviceInstaller1.StartType =
System.ServiceProcess.ServiceStartMode.Manual;
//
// ProjectInstaller
//
this.Installers.AddRange(new
System.Configuration.Install.Installer[] {
this.serviceProcessInstaller1,
this.serviceInstaller1});

}

#endregion

private System.ServiceProcess.ServiceProcessInstaller
serviceProcessInstaller1;
private System.ServiceProcess.ServiceInstaller serviceInstaller1;
}
}





dm3281 said:
I'm really starting to hate writing services -- or trying to, anyway.

Why do I need to rename my project to the service name?

Why do I need to set the "ServiceName" property to my service name?

Why do I need to set a property within my code to the service name?

Are all these required or am I just doing this for consistency purposes?

Now for my real question/problem:

I have written this service and have this in my "SimpeService.cs":

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.ServiceProcess;
using System.Text;

namespace WindowsService2
{
public partial class SimpleService : System.ServiceProcess.ServiceBase
{
private System.Timers.Timer timer;

/// <summary>
/// Required deisgner variable
/// </summary>


public SimpleService()
{
// This call is required by the Windows.Forms Component
Designer
InitializeComponent();

this.timer = new System.Timers.Timer();
this.timer.Enabled = true;
timer.Interval = 5000;
timer.Elapsed += new
System.Timers.ElapsedEventHandler(timer_Elapsed);
CanPauseAndContinue = true;
this.ServiceName = "Hello-World Service";

}

void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
EventLog.WriteEntry("Hello World!");
//throw new Exception("The method or operation is not
implemented.");
}

protected override void OnStart(string[] args)
{
// TODO: Add code here to start your service.
EventLog.WriteEntry("Hello-World Service Started");
timer.Enabled = true;
}

protected override void OnStop()
{
// TODO: Add code here to perform any tear-down necessary to
stop your service.
EventLog.WriteEntry("Hello-World Service Paused");
timer.Enabled = false;
}

protected override void OnPause()
{
EventLog.WriteEntry("Hello-World Service paused");
timer.Enabled = false;
}

protected override void OnContinue()
{
EventLog.WriteEntry("Hello-World Service continued");
timer.Enabled = true;
}

}
}


This is in my "ProjectInstaller.cs" and I have set the service properties,
etc:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration.Install;
using System.ServiceProcess;

namespace WindowsService2
{
[RunInstaller(true)]
public partial class ProjectInstaller : Installer
{
private ServiceInstaller serviceInstaller;
private ServiceProcessInstaller processInstaller;

public ProjectInstaller()
{
InitializeComponent();

processInstaller = new ServiceProcessInstaller();
serviceInstaller = new ServiceInstaller();

// Service will run under system account
processInstaller.Account = ServiceAccount.LocalSystem;

// Service will have Start Type of Manual
serviceInstaller.StartType = ServiceStartMode.Manual;
serviceInstaller.ServiceName = "Hello-World Service";
Installers.Add(serviceInstaller);
Installers.Add(processInstaller);
}
}
}

My "Program.cs" has no changes:

using System.Collections.Generic;
using System.ServiceProcess;
using System.Text;

namespace WindowsService2
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
ServiceBase[] ServicesToRun;

// More than one user Service may run within the same process.
To add
// another service to this process, change the following line
to
// create a second service object. For example,
//
// ServicesToRun = new ServiceBase[] {new Service1(), new
MySecondUserService()};
//
ServicesToRun = new ServiceBase[] { new SimpleService() };

ServiceBase.Run(ServicesToRun);
}
}
}

Now, when I compiel the above, it all compiles fine.

I then jump to Admin Command Prompt and do a "installutil
WindowsService2.exe" and it does the following:

It pops up a dialoge asking me for service credentials. I'm not sure why
because I've defined them within my "ProjectInstaller.cs". But I was
getting this prior to setting any properties under the
"ProjectInstaller.cs" file. Why do I get this?

The format of the credentials appears to only accept
"machinename\username" and nothing else. It took me a while to figure
this out! Arrghhh

After the service is installed, I appear to have two services:

SimpleService2
Hello-World

SimpleService2 won't start.
Hello-World starts and appears to work as expected. I can pause, etc.
without issue and items are appearing in event log.

Executing "InstallUtil -u WindowsService2.exe" appears to get rid of both
services.

I assume SimpleService2 is appearing because that is the name that I use
within the "SimpleService.cs" file??

I assume the crendtial dialogue is coming from this service and not
Hello-World because it appears to have the correct credentials.

How do I get rid of the dialoge all together?

How do I get rid of "SimpleService" installation, since it appears to not
work anyway.

Any help would be appreciated.
 
D

dm3281

If I wanted to use a tool such as AdvancedInstaller from
http://www.caphyon.com/, what would I need to do? Would I need any of these
propteries set within the "ProjectInstallerDesigner.cs" file?

Does AdvancedInstaller allow me to browse to the .EXE, add it to my package,
and then allow me to hardcode or prompt the user for what they want?

What's the best way to do this?
 
J

Jeff Winn

Going to do my best to answer the questions - though you seem to have quite
a few. I've put a block of asterisks at the end of my response since this is
going to be quite large after answering everything. If you have any other
questions please feel free to ask. I work with Windows services a lot. :blush:)
Why do I need to rename my project to the service name?
You don't, I do it to keep everything consistent.

Why do I need to set the "ServiceName" property to my service name?
Because Windows uses this when registering the service, and they must be
unique. Also, if we're on the same page, this is the value used as your
service name when writing events to the event log. Though I could be wrong,
I'm not 100% sure which property you're talking about.

Why do I need to set a property within my code to the service name?
See above.

Are all these required or am I just doing this for consistency purposes?
They're required. If you provide incorrect information the service will have
problems when registering. Which will usually throw an exception that you'll
be able to see if you're registering the service with InstallUtil at the
command prompt.

It pops up a dialoge asking me for service credentials. I'm not sure why
because I've defined them within my "ProjectInstaller.cs". But I was
getting this prior to setting any properties under the
"ProjectInstaller.cs" file. Why do I get this?
Windows services run under a non-interactive user account on the machines.
Typically when a service is first created in Visual Studio the default
settings require a user account the service will run as. You can change this
by opening your ProjectInstaller.cs file (double click it to bring up the
designer) and select your processInstaller component that should be visible.
If you want the service to run as a system account just change the account
to the account type you want. Be cautious about doing this, the system
accounts have unrestricted rights to the machine the service is running on.
The ServiceAccount.User enum requires if the Username and Password
properties on the component aren't set, when the service is being installed
the account information must be prompted. The reason you have to give the
full account (including domain/machine name) is because the service needs
the entire credential when it's starting.

If I wanted to use a tool such as AdvancedInstaller from
http://www.caphyon.com/, what would I need to do? Would I need any of
these propteries set within the "ProjectInstallerDesigner.cs" file?
Does AdvancedInstaller allow me to browse to the .EXE, add it to my
package, and then allow me to hardcode or prompt the user for what they
want?
What's the best way to do this?
This would be a question better suited to be asked by the software vendor. I
typically just use the Setup project available within Visual Studio for
deploying services.

NOTE: InstallUtil will not be available on your target machines as it is not
included with the .NET Framework. You will need to use an installer package
to get the service registered on the deployment machine. Also, about that -
you will need to use a custom installer action pointed to your service
executable to get the installer package to register your service. The
System.Configuration.Install.Installer class (which is the base class for
the ProjectInstaller) you made, handles registering the service with the
machine. You can use .NET Reflector if you want to actually take a look at
the code in the class how it uses the Win32 API and pinvoke if you're
interested in looking under the hood. :blush:)

After the service is installed, I appear to have two services:

SimpleService2
Hello-World

SimpleService2 won't start.
Hello-World starts and appears to work as expected. I can pause, etc.
without issue and items are appearing in event log.

Executing "InstallUtil -u WindowsService2.exe" appears to get rid of both
services.

I assume SimpleService2 is appearing because that is the name that I use
within the "SimpleService.cs" file??
This would be a result of not using a consistent service name throughout the
service. My suggestion would be to do a Find All within the IDE and search
for "SimpleService2" throughout your application and make sure it's updated
to the proper service name.

I assume the crendtial dialogue is coming from this service and not
Hello-World because it appears to have the correct credentials.

How do I get rid of the dialoge all together?
See the above answer on the project installer.

How do I get rid of "SimpleService" installation, since it appears to not
work anyway.
Change the service name in your application back to the original value,
register the service again and finally remove it again. This will get the
old service removed from the machine (hopefully) so it won't be listed.

HINT: When working with Windows services I have found it best to create a
batch file to install and uninstall the services into the program files
folder on my machine when testing. When InstallUtil is executed against the
service assembly the configuration in that executable is what is used during
the install/uninstall process. If you build the software before uninstalling
the old version this is what can result.

**************************************************************************
**************************************************************************

dm3281 said:
I'm really starting to hate writing services -- or trying to, anyway.

Why do I need to rename my project to the service name?

Why do I need to set the "ServiceName" property to my service name?

Why do I need to set a property within my code to the service name?

Are all these required or am I just doing this for consistency purposes?

Now for my real question/problem:

I have written this service and have this in my "SimpeService.cs":

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.ServiceProcess;
using System.Text;

namespace WindowsService2
{
public partial class SimpleService : System.ServiceProcess.ServiceBase
{
private System.Timers.Timer timer;

/// <summary>
/// Required deisgner variable
/// </summary>


public SimpleService()
{
// This call is required by the Windows.Forms Component
Designer
InitializeComponent();

this.timer = new System.Timers.Timer();
this.timer.Enabled = true;
timer.Interval = 5000;
timer.Elapsed += new
System.Timers.ElapsedEventHandler(timer_Elapsed);
CanPauseAndContinue = true;
this.ServiceName = "Hello-World Service";

}

void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
EventLog.WriteEntry("Hello World!");
//throw new Exception("The method or operation is not
implemented.");
}

protected override void OnStart(string[] args)
{
// TODO: Add code here to start your service.
EventLog.WriteEntry("Hello-World Service Started");
timer.Enabled = true;
}

protected override void OnStop()
{
// TODO: Add code here to perform any tear-down necessary to
stop your service.
EventLog.WriteEntry("Hello-World Service Paused");
timer.Enabled = false;
}

protected override void OnPause()
{
EventLog.WriteEntry("Hello-World Service paused");
timer.Enabled = false;
}

protected override void OnContinue()
{
EventLog.WriteEntry("Hello-World Service continued");
timer.Enabled = true;
}

}
}


This is in my "ProjectInstaller.cs" and I have set the service properties,
etc:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration.Install;
using System.ServiceProcess;

namespace WindowsService2
{
[RunInstaller(true)]
public partial class ProjectInstaller : Installer
{
private ServiceInstaller serviceInstaller;
private ServiceProcessInstaller processInstaller;

public ProjectInstaller()
{
InitializeComponent();

processInstaller = new ServiceProcessInstaller();
serviceInstaller = new ServiceInstaller();

// Service will run under system account
processInstaller.Account = ServiceAccount.LocalSystem;

// Service will have Start Type of Manual
serviceInstaller.StartType = ServiceStartMode.Manual;
serviceInstaller.ServiceName = "Hello-World Service";
Installers.Add(serviceInstaller);
Installers.Add(processInstaller);
}
}
}

My "Program.cs" has no changes:

using System.Collections.Generic;
using System.ServiceProcess;
using System.Text;

namespace WindowsService2
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
ServiceBase[] ServicesToRun;

// More than one user Service may run within the same process.
To add
// another service to this process, change the following line
to
// create a second service object. For example,
//
// ServicesToRun = new ServiceBase[] {new Service1(), new
MySecondUserService()};
//
ServicesToRun = new ServiceBase[] { new SimpleService() };

ServiceBase.Run(ServicesToRun);
}
}
}

Now, when I compiel the above, it all compiles fine.

I then jump to Admin Command Prompt and do a "installutil
WindowsService2.exe" and it does the following:

It pops up a dialoge asking me for service credentials. I'm not sure why
because I've defined them within my "ProjectInstaller.cs". But I was
getting this prior to setting any properties under the
"ProjectInstaller.cs" file. Why do I get this?

The format of the credentials appears to only accept
"machinename\username" and nothing else. It took me a while to figure
this out! Arrghhh

After the service is installed, I appear to have two services:

SimpleService2
Hello-World

SimpleService2 won't start.
Hello-World starts and appears to work as expected. I can pause, etc.
without issue and items are appearing in event log.

Executing "InstallUtil -u WindowsService2.exe" appears to get rid of both
services.

I assume SimpleService2 is appearing because that is the name that I use
within the "SimpleService.cs" file??

I assume the crendtial dialogue is coming from this service and not
Hello-World because it appears to have the correct credentials.

How do I get rid of the dialoge all together?

How do I get rid of "SimpleService" installation, since it appears to not
work anyway.

Any help would be appreciated.
 
D

dm3281

Thanks for the quick response, Jeff.

I tried using AdvancedInstaller and it's relatively easy. Of course, only
the professional version supports installing services, but all I have to do
is browse for the .EXE and give it a service name/description and it will
create an MSI. Very cool. I assume if I use this approach, then I can
remove the "Installer" project that was added within VS as that isn't needed
since I won't be using InstallUtil or anything, but maybe I should leave it
for the cases where I want to manually test???



Now, off to another related topic.

What is the best way to debug a Windows service?

I plan on writing a program that scan foldres for XML files, procsess the
XML files, then insert into SQL the information. This will run within a
timer loop every 5 minutes or so.

I was thinking that I should write a console application first and create a
class for my program. This way I can get everything tested and working.

I was then thinking I could create another project for my service program
and add my class from my console project???

I'm not sure how I can actually debug this one I have it all within a
service. I was under the impression that I could install the service, open
VS and attach to the running process after setting my breakpoint and life
would be good. But I do not appear to be able to step thru the code or
anything. I assume I'm doing something wrong here....






Jeff Winn said:
Going to do my best to answer the questions - though you seem to have
quite a few. I've put a block of asterisks at the end of my response since
this is going to be quite large after answering everything. If you have
any other questions please feel free to ask. I work with Windows services
a lot. :blush:)
Why do I need to rename my project to the service name?
You don't, I do it to keep everything consistent.

Why do I need to set the "ServiceName" property to my service name?
Because Windows uses this when registering the service, and they must be
unique. Also, if we're on the same page, this is the value used as your
service name when writing events to the event log. Though I could be
wrong, I'm not 100% sure which property you're talking about.

Why do I need to set a property within my code to the service name?
See above.

Are all these required or am I just doing this for consistency purposes?
They're required. If you provide incorrect information the service will
have problems when registering. Which will usually throw an exception that
you'll be able to see if you're registering the service with InstallUtil
at the command prompt.

It pops up a dialoge asking me for service credentials. I'm not sure why
because I've defined them within my "ProjectInstaller.cs". But I was
getting this prior to setting any properties under the
"ProjectInstaller.cs" file. Why do I get this?
Windows services run under a non-interactive user account on the machines.
Typically when a service is first created in Visual Studio the default
settings require a user account the service will run as. You can change
this by opening your ProjectInstaller.cs file (double click it to bring up
the designer) and select your processInstaller component that should be
visible. If you want the service to run as a system account just change
the account to the account type you want. Be cautious about doing this,
the system accounts have unrestricted rights to the machine the service is
running on. The ServiceAccount.User enum requires if the Username and
Password properties on the component aren't set, when the service is being
installed the account information must be prompted. The reason you have to
give the full account (including domain/machine name) is because the
service needs the entire credential when it's starting.

If I wanted to use a tool such as AdvancedInstaller from
http://www.caphyon.com/, what would I need to do? Would I need any of
these propteries set within the "ProjectInstallerDesigner.cs" file?
Does AdvancedInstaller allow me to browse to the .EXE, add it to my
package, and then allow me to hardcode or prompt the user for what they
want?
What's the best way to do this?
This would be a question better suited to be asked by the software vendor.
I typically just use the Setup project available within Visual Studio for
deploying services.

NOTE: InstallUtil will not be available on your target machines as it is
not included with the .NET Framework. You will need to use an installer
package to get the service registered on the deployment machine. Also,
about that - you will need to use a custom installer action pointed to
your service executable to get the installer package to register your
service. The System.Configuration.Install.Installer class (which is the
base class for the ProjectInstaller) you made, handles registering the
service with the machine. You can use .NET Reflector if you want to
actually take a look at the code in the class how it uses the Win32 API
and pinvoke if you're interested in looking under the hood. :blush:)

After the service is installed, I appear to have two services:

SimpleService2
Hello-World

SimpleService2 won't start.
Hello-World starts and appears to work as expected. I can pause, etc.
without issue and items are appearing in event log.

Executing "InstallUtil -u WindowsService2.exe" appears to get rid of both
services.

I assume SimpleService2 is appearing because that is the name that I use
within the "SimpleService.cs" file??
This would be a result of not using a consistent service name throughout
the service. My suggestion would be to do a Find All within the IDE and
search for "SimpleService2" throughout your application and make sure it's
updated to the proper service name.

I assume the crendtial dialogue is coming from this service and not
Hello-World because it appears to have the correct credentials.

How do I get rid of the dialoge all together?
See the above answer on the project installer.

How do I get rid of "SimpleService" installation, since it appears to not
work anyway.
Change the service name in your application back to the original value,
register the service again and finally remove it again. This will get the
old service removed from the machine (hopefully) so it won't be listed.

HINT: When working with Windows services I have found it best to create a
batch file to install and uninstall the services into the program files
folder on my machine when testing. When InstallUtil is executed against
the service assembly the configuration in that executable is what is used
during the install/uninstall process. If you build the software before
uninstalling the old version this is what can result.

**************************************************************************
**************************************************************************

dm3281 said:
I'm really starting to hate writing services -- or trying to, anyway.

Why do I need to rename my project to the service name?

Why do I need to set the "ServiceName" property to my service name?

Why do I need to set a property within my code to the service name?

Are all these required or am I just doing this for consistency purposes?

Now for my real question/problem:

I have written this service and have this in my "SimpeService.cs":

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.ServiceProcess;
using System.Text;

namespace WindowsService2
{
public partial class SimpleService : System.ServiceProcess.ServiceBase
{
private System.Timers.Timer timer;

/// <summary>
/// Required deisgner variable
/// </summary>


public SimpleService()
{
// This call is required by the Windows.Forms Component
Designer
InitializeComponent();

this.timer = new System.Timers.Timer();
this.timer.Enabled = true;
timer.Interval = 5000;
timer.Elapsed += new
System.Timers.ElapsedEventHandler(timer_Elapsed);
CanPauseAndContinue = true;
this.ServiceName = "Hello-World Service";

}

void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs
e)
{
EventLog.WriteEntry("Hello World!");
//throw new Exception("The method or operation is not
implemented.");
}

protected override void OnStart(string[] args)
{
// TODO: Add code here to start your service.
EventLog.WriteEntry("Hello-World Service Started");
timer.Enabled = true;
}

protected override void OnStop()
{
// TODO: Add code here to perform any tear-down necessary to
stop your service.
EventLog.WriteEntry("Hello-World Service Paused");
timer.Enabled = false;
}

protected override void OnPause()
{
EventLog.WriteEntry("Hello-World Service paused");
timer.Enabled = false;
}

protected override void OnContinue()
{
EventLog.WriteEntry("Hello-World Service continued");
timer.Enabled = true;
}

}
}


This is in my "ProjectInstaller.cs" and I have set the service
properties, etc:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration.Install;
using System.ServiceProcess;

namespace WindowsService2
{
[RunInstaller(true)]
public partial class ProjectInstaller : Installer
{
private ServiceInstaller serviceInstaller;
private ServiceProcessInstaller processInstaller;

public ProjectInstaller()
{
InitializeComponent();

processInstaller = new ServiceProcessInstaller();
serviceInstaller = new ServiceInstaller();

// Service will run under system account
processInstaller.Account = ServiceAccount.LocalSystem;

// Service will have Start Type of Manual
serviceInstaller.StartType = ServiceStartMode.Manual;
serviceInstaller.ServiceName = "Hello-World Service";
Installers.Add(serviceInstaller);
Installers.Add(processInstaller);
}
}
}

My "Program.cs" has no changes:

using System.Collections.Generic;
using System.ServiceProcess;
using System.Text;

namespace WindowsService2
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
ServiceBase[] ServicesToRun;

// More than one user Service may run within the same process.
To add
// another service to this process, change the following line
to
// create a second service object. For example,
//
// ServicesToRun = new ServiceBase[] {new Service1(), new
MySecondUserService()};
//
ServicesToRun = new ServiceBase[] { new SimpleService() };

ServiceBase.Run(ServicesToRun);
}
}
}

Now, when I compiel the above, it all compiles fine.

I then jump to Admin Command Prompt and do a "installutil
WindowsService2.exe" and it does the following:

It pops up a dialoge asking me for service credentials. I'm not sure why
because I've defined them within my "ProjectInstaller.cs". But I was
getting this prior to setting any properties under the
"ProjectInstaller.cs" file. Why do I get this?

The format of the credentials appears to only accept
"machinename\username" and nothing else. It took me a while to figure
this out! Arrghhh

After the service is installed, I appear to have two services:

SimpleService2
Hello-World

SimpleService2 won't start.
Hello-World starts and appears to work as expected. I can pause, etc.
without issue and items are appearing in event log.

Executing "InstallUtil -u WindowsService2.exe" appears to get rid of both
services.

I assume SimpleService2 is appearing because that is the name that I use
within the "SimpleService.cs" file??

I assume the crendtial dialogue is coming from this service and not
Hello-World because it appears to have the correct credentials.

How do I get rid of the dialoge all together?

How do I get rid of "SimpleService" installation, since it appears to not
work anyway.

Any help would be appreciated.
 
J

Jeff Winn

There's more to installing services than simply deploying the executable on
the target machine. I didn't get too in depth on the installation, but in
order for a service to be deployed and registered on the target machine you
must have an installer class in there.

Deep within the System.Configuration.Install.Installer class there's some
pinvoke operations that open the ServiceControlManager (SCM) used by Windows
for service/device management and perform the installation into Windows. One
of the things you need to do when installing services is in your MSI package
you will need to create custom installer actions that tell the service to
execute the installers that are located in your project. That's what the
[RunInstaller(true)] attribute is for you see decorating your
ProjectInstaller class below. Without the custom action being executed the
service may be copied to the machine, but the service will not be registered
with the computer.

If you really need to deploy services and you don't want to pay for the pro
version of that software you mentioned, you might want to just use the setup
projects that come with Visual Studio. Somehow I have the feeling the
software isn't going to install the service properly unless you buy the
upgraded version.

As for your question regarding testing, yes you will need the
ProjectInstaller class in your service for the InstallUtil.exe to properly
register the service on the machine.

dm3281 said:
Thanks for the quick response, Jeff.

I tried using AdvancedInstaller and it's relatively easy. Of course, only
the professional version supports installing services, but all I have to
do is browse for the .EXE and give it a service name/description and it
will create an MSI. Very cool. I assume if I use this approach, then I
can remove the "Installer" project that was added within VS as that isn't
needed since I won't be using InstallUtil or anything, but maybe I should
leave it for the cases where I want to manually test???



Now, off to another related topic.

What is the best way to debug a Windows service?

I plan on writing a program that scan foldres for XML files, procsess the
XML files, then insert into SQL the information. This will run within a
timer loop every 5 minutes or so.

I was thinking that I should write a console application first and create
a class for my program. This way I can get everything tested and working.

I was then thinking I could create another project for my service program
and add my class from my console project???

I'm not sure how I can actually debug this one I have it all within a
service. I was under the impression that I could install the service,
open VS and attach to the running process after setting my breakpoint and
life would be good. But I do not appear to be able to step thru the code
or anything. I assume I'm doing something wrong here....






Jeff Winn said:
Going to do my best to answer the questions - though you seem to have
quite a few. I've put a block of asterisks at the end of my response
since this is going to be quite large after answering everything. If you
have any other questions please feel free to ask. I work with Windows
services a lot. :blush:)
Why do I need to rename my project to the service name?
You don't, I do it to keep everything consistent.

Why do I need to set the "ServiceName" property to my service name?
Because Windows uses this when registering the service, and they must be
unique. Also, if we're on the same page, this is the value used as your
service name when writing events to the event log. Though I could be
wrong, I'm not 100% sure which property you're talking about.

Why do I need to set a property within my code to the service name?
See above.

Are all these required or am I just doing this for consistency purposes?
They're required. If you provide incorrect information the service will
have problems when registering. Which will usually throw an exception
that you'll be able to see if you're registering the service with
InstallUtil at the command prompt.

It pops up a dialoge asking me for service credentials. I'm not sure
why because I've defined them within my "ProjectInstaller.cs". But I
was getting this prior to setting any properties under the
"ProjectInstaller.cs" file. Why do I get this?
Windows services run under a non-interactive user account on the
machines. Typically when a service is first created in Visual Studio the
default settings require a user account the service will run as. You can
change this by opening your ProjectInstaller.cs file (double click it to
bring up the designer) and select your processInstaller component that
should be visible. If you want the service to run as a system account
just change the account to the account type you want. Be cautious about
doing this, the system accounts have unrestricted rights to the machine
the service is running on. The ServiceAccount.User enum requires if the
Username and Password properties on the component aren't set, when the
service is being installed the account information must be prompted. The
reason you have to give the full account (including domain/machine name)
is because the service needs the entire credential when it's starting.

If I wanted to use a tool such as AdvancedInstaller from
http://www.caphyon.com/, what would I need to do? Would I need any of
these propteries set within the "ProjectInstallerDesigner.cs" file?
Does AdvancedInstaller allow me to browse to the .EXE, add it to my
package, and then allow me to hardcode or prompt the user for what they
want?
What's the best way to do this?
This would be a question better suited to be asked by the software
vendor. I typically just use the Setup project available within Visual
Studio for deploying services.

NOTE: InstallUtil will not be available on your target machines as it is
not included with the .NET Framework. You will need to use an installer
package to get the service registered on the deployment machine. Also,
about that - you will need to use a custom installer action pointed to
your service executable to get the installer package to register your
service. The System.Configuration.Install.Installer class (which is the
base class for the ProjectInstaller) you made, handles registering the
service with the machine. You can use .NET Reflector if you want to
actually take a look at the code in the class how it uses the Win32 API
and pinvoke if you're interested in looking under the hood. :blush:)

After the service is installed, I appear to have two services:

SimpleService2
Hello-World

SimpleService2 won't start.
Hello-World starts and appears to work as expected. I can pause, etc.
without issue and items are appearing in event log.

Executing "InstallUtil -u WindowsService2.exe" appears to get rid of
both services.

I assume SimpleService2 is appearing because that is the name that I use
within the "SimpleService.cs" file??
This would be a result of not using a consistent service name throughout
the service. My suggestion would be to do a Find All within the IDE and
search for "SimpleService2" throughout your application and make sure
it's updated to the proper service name.

I assume the crendtial dialogue is coming from this service and not
Hello-World because it appears to have the correct credentials.

How do I get rid of the dialoge all together?
See the above answer on the project installer.

How do I get rid of "SimpleService" installation, since it appears to
not work anyway.
Change the service name in your application back to the original value,
register the service again and finally remove it again. This will get the
old service removed from the machine (hopefully) so it won't be listed.

HINT: When working with Windows services I have found it best to create a
batch file to install and uninstall the services into the program files
folder on my machine when testing. When InstallUtil is executed against
the service assembly the configuration in that executable is what is used
during the install/uninstall process. If you build the software before
uninstalling the old version this is what can result.

**************************************************************************
**************************************************************************

dm3281 said:
I'm really starting to hate writing services -- or trying to, anyway.

Why do I need to rename my project to the service name?

Why do I need to set the "ServiceName" property to my service name?

Why do I need to set a property within my code to the service name?

Are all these required or am I just doing this for consistency purposes?

Now for my real question/problem:

I have written this service and have this in my "SimpeService.cs":

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.ServiceProcess;
using System.Text;

namespace WindowsService2
{
public partial class SimpleService :
System.ServiceProcess.ServiceBase
{
private System.Timers.Timer timer;

/// <summary>
/// Required deisgner variable
/// </summary>


public SimpleService()
{
// This call is required by the Windows.Forms Component
Designer
InitializeComponent();

this.timer = new System.Timers.Timer();
this.timer.Enabled = true;
timer.Interval = 5000;
timer.Elapsed += new
System.Timers.ElapsedEventHandler(timer_Elapsed);
CanPauseAndContinue = true;
this.ServiceName = "Hello-World Service";

}

void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs
e)
{
EventLog.WriteEntry("Hello World!");
//throw new Exception("The method or operation is not
implemented.");
}

protected override void OnStart(string[] args)
{
// TODO: Add code here to start your service.
EventLog.WriteEntry("Hello-World Service Started");
timer.Enabled = true;
}

protected override void OnStop()
{
// TODO: Add code here to perform any tear-down necessary to
stop your service.
EventLog.WriteEntry("Hello-World Service Paused");
timer.Enabled = false;
}

protected override void OnPause()
{
EventLog.WriteEntry("Hello-World Service paused");
timer.Enabled = false;
}

protected override void OnContinue()
{
EventLog.WriteEntry("Hello-World Service continued");
timer.Enabled = true;
}

}
}


This is in my "ProjectInstaller.cs" and I have set the service
properties, etc:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration.Install;
using System.ServiceProcess;

namespace WindowsService2
{
[RunInstaller(true)]
public partial class ProjectInstaller : Installer
{
private ServiceInstaller serviceInstaller;
private ServiceProcessInstaller processInstaller;

public ProjectInstaller()
{
InitializeComponent();

processInstaller = new ServiceProcessInstaller();
serviceInstaller = new ServiceInstaller();

// Service will run under system account
processInstaller.Account = ServiceAccount.LocalSystem;

// Service will have Start Type of Manual
serviceInstaller.StartType = ServiceStartMode.Manual;
serviceInstaller.ServiceName = "Hello-World Service";
Installers.Add(serviceInstaller);
Installers.Add(processInstaller);
}
}
}

My "Program.cs" has no changes:

using System.Collections.Generic;
using System.ServiceProcess;
using System.Text;

namespace WindowsService2
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
ServiceBase[] ServicesToRun;

// More than one user Service may run within the same
process. To add
// another service to this process, change the following line
to
// create a second service object. For example,
//
// ServicesToRun = new ServiceBase[] {new Service1(), new
MySecondUserService()};
//
ServicesToRun = new ServiceBase[] { new SimpleService() };

ServiceBase.Run(ServicesToRun);
}
}
}

Now, when I compiel the above, it all compiles fine.

I then jump to Admin Command Prompt and do a "installutil
WindowsService2.exe" and it does the following:

It pops up a dialoge asking me for service credentials. I'm not sure
why because I've defined them within my "ProjectInstaller.cs". But I
was getting this prior to setting any properties under the
"ProjectInstaller.cs" file. Why do I get this?

The format of the credentials appears to only accept
"machinename\username" and nothing else. It took me a while to figure
this out! Arrghhh

After the service is installed, I appear to have two services:

SimpleService2
Hello-World

SimpleService2 won't start.
Hello-World starts and appears to work as expected. I can pause, etc.
without issue and items are appearing in event log.

Executing "InstallUtil -u WindowsService2.exe" appears to get rid of
both services.

I assume SimpleService2 is appearing because that is the name that I use
within the "SimpleService.cs" file??

I assume the crendtial dialogue is coming from this service and not
Hello-World because it appears to have the correct credentials.

How do I get rid of the dialoge all together?

How do I get rid of "SimpleService" installation, since it appears to
not work anyway.

Any help would be appreciated.
 
J

Jeff Winn

Oops, I must be getting tired - I completely ignored the other half of your
question in my last response.

Debugging services: the part more annoying than writing them. Basically,
since a Windows service cannot be started directly within the IDE this is
where that batch file I was talking about earlier comes into play. At the
end of this message I've included an older version of the batch file I've
been using for years when working on these services. Hopefully it'll
alleviate some of the headaches you'll run into when working with Windows
services.

You'll need to manually start the service, and then attach the debugger to
the process like you said earlier. Also, if you're running the service under
another account (system accounts included) make sure you check the box for
"Show processes from all users" so you'll be able to see the service when
it's running. Another note about Vista - if you're using Vista and the
service is under a system or other user account you'll need to run Visual
Studio as administrator or disable the UAC). If you want to debug the setup
and teardown methods (OnStart and OnStop) of your service, you'll need to
add a line in the method(s) to pause the thread temporarily to give you
enough time to attach the debugger. I typically pause the thread for 10
seconds to give myself enough time. That's what the /debug switch is for
you'll see in the bottom of the batch file i've included. I just checked the
args when the service was starting to see if it's included in there, and if
so pause the thread. Just don't pause it too long - if the service doesn't
start fast enough Windows kills the process - sometimes even when you're
trying to debug it.

Just copy everything from inside the block of asterisks (excluding the line
of asterisks) into a .bat file. You'll only need to modify the first few
lines of the batch file to get it to work with your service you wrote. This
will handle uninstalling any existing version of the service you have on the
machine, copying the new build, and running installutil on the new service
as well as starting the service for you. If nothing else it'll give you a
good starting point for your own file like this. Just put the file in the
folder with your .*proj file.
*************************************************************************************

@echo off

set INSTALL_FOLDER=MyService
set EXECUTABLE_NAME=MyService.exe
set DOTNET_VERSION=2.0.50727
set SERVICE_NAME=MyService
set SERVICE_DESC=My First Service!
set COPYRIGHT_NOTICE=You won't need this more than likely

set INSTALL_PATH=%PROGRAMFILES%\%INSTALL_FOLDER%
set FULL_PATH=%PROGRAMFILES%\%INSTALL_FOLDER%\%EXECUTABLE_NAME%

cls
echo %SERVICE_DESC% Installer
echo %COPYRIGHT_NOTICE%
echo.

if [%1] == [/?] goto ShowSyntax
if [%1] == [?] goto ShowSyntax
if [%1] == [-?] goto ShowSyntax

if not exist
"%SYSTEMROOT%\Microsoft.NET\Framework\v%DOTNET_VERSION%\InstallUtil.exe"
goto NoDotNet
goto StartUninstall

:NoDotNet
echo The Microsoft .NET Framework v%DOTNET_VERSION% was not found on this
machine.
echo Please install the framework before continuing with the installation.
goto FinishBatch

:StartUninstall
if not exist "%FULL_PATH%" goto StartInstall
echo.
echo ***********************************
echo * STOPPING THE SERVICE *
echo ***********************************
net stop %SERVICE_NAME%
echo.

if /I [%1] == [/s] goto ExitBatch

echo.
echo ***********************************
echo * UNINSTALLING PREVIOUS *
echo ***********************************
echo.
%SYSTEMROOT%\Microsoft.NET\Framework\v%DOTNET_VERSION%\InstallUtil /u
"%FULL_PATH%"
echo.

if /I [%1] == [/u] goto RemoveFolder

:StartInstall
echo.
echo ***********************************
echo * COPYING THE NEW BUILD *
echo ***********************************
echo.
if exist "%INSTALL_PATH%" goto BeginCopying
md "%INSTALL_PATH%"

:BeginCopying
if /I [%1] == [/r] goto CopyRelease
if /I [%2] == [/r] goto CopyRelease

copy /y ".\bin\Debug\*.*" "%INSTALL_PATH%"
echo.
echo.
echo ***********************************
echo * SWAPPING CONFIG FILES *
echo ***********************************
echo.
del "%INSTALL_PATH%\connections.config"
ren "%INSTALL_PATH%\development.config" "connections.config"

goto FinishedCopyingBuild

:CopyRelease
copy /y ".\bin\Release\*.*" "%INSTALL_PATH%"

:FinishedCopyingBuild
echo.
echo.
echo ***********************************
echo * INSTALLING BUILD *
echo ***********************************
echo.
%SYSTEMROOT%\Microsoft.NET\Framework\v%DOTNET_VERSION%\InstallUtil
"%FULL_PATH%"
del *.InstallLog
echo.
echo.

if /I [%1] == [/n] goto BypassStartup

echo ***********************************
echo * STARTING THE SERVICE *
echo ***********************************
echo.
if /I [%1] == [/r] goto StartRelease

net start %SERVICE_NAME% /debug
goto ExitBatch

:StartRelease
net start %SERVICE_NAME%
goto ExitBatch

:BypassStartup
echo ***********************************
echo * BYPASSING STARTUP *
echo ***********************************
goto ExitBatch

:ShowSyntax
echo Installs the %SERVICE_DESC% to the machine.
echo.
echo INSTALL [OPTION]
echo.
echo /S Forces the service to stop.
echo.
echo /U Uninstalls the service from the installation folder.
echo.
echo /N Bypasses startup for the service and only copies and installs
echo the service to the machine.
echo.
echo /R Copies the release build to the installation folder.
echo.
goto FinishBatch

:RemoveFolder
echo ***********************************
echo * REMOVING INSTALLATION FOLDER *
echo ***********************************
echo.
echo.
rd /s /q "%INSTALL_PATH%"
goto ExitBatch

:ExitBatch
echo | time | find "current"
echo | date | find "current"
echo.

:FinishBatch

*************************************************************************************

Jeff Winn said:
There's more to installing services than simply deploying the executable
on the target machine. I didn't get too in depth on the installation, but
in order for a service to be deployed and registered on the target machine
you must have an installer class in there.

Deep within the System.Configuration.Install.Installer class there's some
pinvoke operations that open the ServiceControlManager (SCM) used by
Windows for service/device management and perform the installation into
Windows. One of the things you need to do when installing services is in
your MSI package you will need to create custom installer actions that
tell the service to execute the installers that are located in your
project. That's what the [RunInstaller(true)] attribute is for you see
decorating your ProjectInstaller class below. Without the custom action
being executed the service may be copied to the machine, but the service
will not be registered with the computer.

If you really need to deploy services and you don't want to pay for the
pro version of that software you mentioned, you might want to just use the
setup projects that come with Visual Studio. Somehow I have the feeling
the software isn't going to install the service properly unless you buy
the upgraded version.

As for your question regarding testing, yes you will need the
ProjectInstaller class in your service for the InstallUtil.exe to properly
register the service on the machine.

dm3281 said:
Thanks for the quick response, Jeff.

I tried using AdvancedInstaller and it's relatively easy. Of course,
only the professional version supports installing services, but all I
have to do is browse for the .EXE and give it a service name/description
and it will create an MSI. Very cool. I assume if I use this approach,
then I can remove the "Installer" project that was added within VS as
that isn't needed since I won't be using InstallUtil or anything, but
maybe I should leave it for the cases where I want to manually test???



Now, off to another related topic.

What is the best way to debug a Windows service?

I plan on writing a program that scan foldres for XML files, procsess the
XML files, then insert into SQL the information. This will run within a
timer loop every 5 minutes or so.

I was thinking that I should write a console application first and create
a class for my program. This way I can get everything tested and
working.

I was then thinking I could create another project for my service program
and add my class from my console project???

I'm not sure how I can actually debug this one I have it all within a
service. I was under the impression that I could install the service,
open VS and attach to the running process after setting my breakpoint and
life would be good. But I do not appear to be able to step thru the
code or anything. I assume I'm doing something wrong here....






Jeff Winn said:
Going to do my best to answer the questions - though you seem to have
quite a few. I've put a block of asterisks at the end of my response
since this is going to be quite large after answering everything. If you
have any other questions please feel free to ask. I work with Windows
services a lot. :blush:)

Why do I need to rename my project to the service name?
You don't, I do it to keep everything consistent.


Why do I need to set the "ServiceName" property to my service name?
Because Windows uses this when registering the service, and they must be
unique. Also, if we're on the same page, this is the value used as your
service name when writing events to the event log. Though I could be
wrong, I'm not 100% sure which property you're talking about.


Why do I need to set a property within my code to the service name?
See above.


Are all these required or am I just doing this for consistency
purposes?
They're required. If you provide incorrect information the service will
have problems when registering. Which will usually throw an exception
that you'll be able to see if you're registering the service with
InstallUtil at the command prompt.


It pops up a dialoge asking me for service credentials. I'm not sure
why because I've defined them within my "ProjectInstaller.cs". But I
was getting this prior to setting any properties under the
"ProjectInstaller.cs" file. Why do I get this?
Windows services run under a non-interactive user account on the
machines. Typically when a service is first created in Visual Studio the
default settings require a user account the service will run as. You can
change this by opening your ProjectInstaller.cs file (double click it to
bring up the designer) and select your processInstaller component that
should be visible. If you want the service to run as a system account
just change the account to the account type you want. Be cautious about
doing this, the system accounts have unrestricted rights to the machine
the service is running on. The ServiceAccount.User enum requires if the
Username and Password properties on the component aren't set, when the
service is being installed the account information must be prompted. The
reason you have to give the full account (including domain/machine name)
is because the service needs the entire credential when it's starting.


If I wanted to use a tool such as AdvancedInstaller from
http://www.caphyon.com/, what would I need to do? Would I need any of
these propteries set within the "ProjectInstallerDesigner.cs" file?
Does AdvancedInstaller allow me to browse to the .EXE, add it to my
package, and then allow me to hardcode or prompt the user for what they
want?
What's the best way to do this?
This would be a question better suited to be asked by the software
vendor. I typically just use the Setup project available within Visual
Studio for deploying services.

NOTE: InstallUtil will not be available on your target machines as it is
not included with the .NET Framework. You will need to use an installer
package to get the service registered on the deployment machine. Also,
about that - you will need to use a custom installer action pointed to
your service executable to get the installer package to register your
service. The System.Configuration.Install.Installer class (which is the
base class for the ProjectInstaller) you made, handles registering the
service with the machine. You can use .NET Reflector if you want to
actually take a look at the code in the class how it uses the Win32 API
and pinvoke if you're interested in looking under the hood. :blush:)


After the service is installed, I appear to have two services:

SimpleService2
Hello-World

SimpleService2 won't start.
Hello-World starts and appears to work as expected. I can pause, etc.
without issue and items are appearing in event log.

Executing "InstallUtil -u WindowsService2.exe" appears to get rid of
both services.

I assume SimpleService2 is appearing because that is the name that I
use within the "SimpleService.cs" file??
This would be a result of not using a consistent service name throughout
the service. My suggestion would be to do a Find All within the IDE and
search for "SimpleService2" throughout your application and make sure
it's updated to the proper service name.


I assume the crendtial dialogue is coming from this service and not
Hello-World because it appears to have the correct credentials.

How do I get rid of the dialoge all together?
See the above answer on the project installer.


How do I get rid of "SimpleService" installation, since it appears to
not work anyway.
Change the service name in your application back to the original value,
register the service again and finally remove it again. This will get
the old service removed from the machine (hopefully) so it won't be
listed.

HINT: When working with Windows services I have found it best to create
a batch file to install and uninstall the services into the program
files folder on my machine when testing. When InstallUtil is executed
against the service assembly the configuration in that executable is
what is used during the install/uninstall process. If you build the
software before uninstalling the old version this is what can result.

**************************************************************************
**************************************************************************

I'm really starting to hate writing services -- or trying to, anyway.

Why do I need to rename my project to the service name?

Why do I need to set the "ServiceName" property to my service name?

Why do I need to set a property within my code to the service name?

Are all these required or am I just doing this for consistency
purposes?

Now for my real question/problem:

I have written this service and have this in my "SimpeService.cs":

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.ServiceProcess;
using System.Text;

namespace WindowsService2
{
public partial class SimpleService :
System.ServiceProcess.ServiceBase
{
private System.Timers.Timer timer;

/// <summary>
/// Required deisgner variable
/// </summary>


public SimpleService()
{
// This call is required by the Windows.Forms Component
Designer
InitializeComponent();

this.timer = new System.Timers.Timer();
this.timer.Enabled = true;
timer.Interval = 5000;
timer.Elapsed += new
System.Timers.ElapsedEventHandler(timer_Elapsed);
CanPauseAndContinue = true;
this.ServiceName = "Hello-World Service";

}

void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs
e)
{
EventLog.WriteEntry("Hello World!");
//throw new Exception("The method or operation is not
implemented.");
}

protected override void OnStart(string[] args)
{
// TODO: Add code here to start your service.
EventLog.WriteEntry("Hello-World Service Started");
timer.Enabled = true;
}

protected override void OnStop()
{
// TODO: Add code here to perform any tear-down necessary to
stop your service.
EventLog.WriteEntry("Hello-World Service Paused");
timer.Enabled = false;
}

protected override void OnPause()
{
EventLog.WriteEntry("Hello-World Service paused");
timer.Enabled = false;
}

protected override void OnContinue()
{
EventLog.WriteEntry("Hello-World Service continued");
timer.Enabled = true;
}

}
}


This is in my "ProjectInstaller.cs" and I have set the service
properties, etc:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration.Install;
using System.ServiceProcess;

namespace WindowsService2
{
[RunInstaller(true)]
public partial class ProjectInstaller : Installer
{
private ServiceInstaller serviceInstaller;
private ServiceProcessInstaller processInstaller;

public ProjectInstaller()
{
InitializeComponent();

processInstaller = new ServiceProcessInstaller();
serviceInstaller = new ServiceInstaller();

// Service will run under system account
processInstaller.Account = ServiceAccount.LocalSystem;

// Service will have Start Type of Manual
serviceInstaller.StartType = ServiceStartMode.Manual;
serviceInstaller.ServiceName = "Hello-World Service";
Installers.Add(serviceInstaller);
Installers.Add(processInstaller);
}
}
}

My "Program.cs" has no changes:

using System.Collections.Generic;
using System.ServiceProcess;
using System.Text;

namespace WindowsService2
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
ServiceBase[] ServicesToRun;

// More than one user Service may run within the same
process. To add
// another service to this process, change the following
line to
// create a second service object. For example,
//
// ServicesToRun = new ServiceBase[] {new Service1(), new
MySecondUserService()};
//
ServicesToRun = new ServiceBase[] { new SimpleService() };

ServiceBase.Run(ServicesToRun);
}
}
}

Now, when I compiel the above, it all compiles fine.

I then jump to Admin Command Prompt and do a "installutil
WindowsService2.exe" and it does the following:

It pops up a dialoge asking me for service credentials. I'm not sure
why because I've defined them within my "ProjectInstaller.cs". But I
was getting this prior to setting any properties under the
"ProjectInstaller.cs" file. Why do I get this?

The format of the credentials appears to only accept
"machinename\username" and nothing else. It took me a while to figure
this out! Arrghhh

After the service is installed, I appear to have two services:

SimpleService2
Hello-World

SimpleService2 won't start.
Hello-World starts and appears to work as expected. I can pause, etc.
without issue and items are appearing in event log.

Executing "InstallUtil -u WindowsService2.exe" appears to get rid of
both services.

I assume SimpleService2 is appearing because that is the name that I
use within the "SimpleService.cs" file??

I assume the crendtial dialogue is coming from this service and not
Hello-World because it appears to have the correct credentials.

How do I get rid of the dialoge all together?

How do I get rid of "SimpleService" installation, since it appears to
not work anyway.

Any help would be appreciated.
 
J

Joel Lucsy

dm3281 said:
I plan on writing a program that scan foldres for XML files, procsess
the XML files, then insert into SQL the information. This will run
within a timer loop every 5 minutes or so.

A far simpler idea may be to use the task scheduler to run your program
every 5 minutes. No service needed.
 

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