New to windows services, can't get installer to work

V

vtxr1300

I've followed 2 very similar tutorials on creating a windows service
and an installer. But, after successfully compiling it, I try to do
the InstallUtil command, but I get a badimageformatexception. I tried
to do some searching on that exception, but all I could find was a
small blurb on MSs site about C++ which I'm not using. Can anyone see
a problem in this code? Thanks.

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Diagnostics;

namespace FaxWatcher
{
class Stalker : IDisposable
{
#region members
private string _path = string.Empty;
private string _filter = string.Empty;
private string _savepath = string.Empty;
private string _logfile = string.Empty;
private DateTime dt = DateTime.Now;

FileSystemWatcher fsw = null;
#endregion

#region cstor
public Stalker(string stalkpath, string savepath, string
filter)
{
_path = stalkpath.Trim();
_filter = filter.Trim();
_savepath = savepath.Trim();
_logfile =
Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);

fsw = new FileSystemWatcher();
fsw.Path = _path;
fsw.Filter = _filter;
fsw.NotifyFilter = NotifyFilters.CreationTime;
fsw.EnableRaisingEvents = true;
fsw.Changed += new FileSystemEventHandler(fsw_Changed);
}
#endregion

#region directory changed event
void fsw_Changed(object sender, FileSystemEventArgs e)
{
string filepath = e.FullPath;
string filename = e.Name;
string tofolder = dt.ToShortDateString().Replace("/",
string.Empty);

if (!Directory.Exists(_savepath + "/" + tofolder))
Directory.CreateDirectory(_savepath + "/" + tofolder);

if (File.Exists(_savepath + "/" + tofolder + "/" +
filename))
GetNewFileName(ref filename, _savepath + "/" +
tofolder);

try
{
//do we need to do some renaming here?
File.Copy(filepath, _savepath + "/" + tofolder + "/" +
filename);
File.Delete(filepath);
}
#region error occurred, log to text file
catch (Exception exc)
{
try
{
Stream st = null;
if (!File.Exists(_logfile + "/log.txt"))
st = File.Create(_logfile + "/log.txt");
else
st = File.Open(_logfile + "/log.txt",
FileMode.Append);

TextWriter tw = new StreamWriter(st);
tw.WriteLine(filepath + " | " + exc.ToString());
tw.Close(); tw.Dispose();
st.Dispose(); st = null;
}
catch (Exception ex) { }
}
#endregion
}
#endregion

#region GetNewFileName
private void GetNewFileName(ref string filename, string path)
{

int i = 1;
string tmpName = filename;

while (File.Exists(path + "\\" + tmpName))
{
tmpName = String.Concat(filename.Substring(0,
filename.LastIndexOf(".")), i,
filename.Substring(filename.LastIndexOf(".")));
i++;
}

filename = tmpName;
}
#endregion

#region properties
public string StalkPath
{
set { _path = value.Trim(); }
get { return _path; }
}

public string StalkFilter
{
set { _filter = value.Trim(); }
get { return _filter; }
}
#endregion

#region cleanup
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}

protected virtual void Dispose(bool disposing)
{
if (disposing)
if (fsw != null)
fsw.Dispose(); fsw = null;
}

~Stalker()
{
Dispose(false);
}
#endregion
}
}

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

namespace FaxWatcher
{
class StalkerService : ServiceBase
{
Stalker s = null;

public StalkerService()
{
this.ServiceName = "Stalker";
this.CanStop = true;
this.CanPauseAndContinue = false;
this.AutoLog = false;
}

public static void Main()
{
System.ServiceProcess.ServiceBase.Run(new
StalkerService());

}

protected override void OnStart(string[] args)
{
if (args.Length > 2)
s = new Stalker(args[0], args[1], args[2]);
}

protected override void OnShutdown()
{
if (s != null)
s.Dispose();
base.OnShutdown();
}
}
}


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

namespace FaxWatcher
{
[RunInstaller(true)]
public class StalkerServiceInstaller : Installer
{
private ServiceProcessInstaller processInstaller;
private ServiceInstaller serviceInstaller;

public StalkerServiceInstaller()
{
processInstaller = new ServiceProcessInstaller();
serviceInstaller = new ServiceInstaller();

processInstaller.Account = ServiceAccount.LocalSystem;
serviceInstaller.StartType = ServiceStartMode.Manual;
serviceInstaller.ServiceName = "Stalker";

Installers.Add(serviceInstaller);
Installers.Add(processInstaller);
}
}
}
 
I

Ignacio Machin \( .NET/ C# MVP \)

Hi,

Are you using VS ?
If so did you select "Windows Service" as the project type?
If so, right click in either the designer view of the service or in the
project name and select Add Installer.
This will include all what you need to install it, set the properties to
your desired values and right click in the Setup project name you will have
an "Install service" option


--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation


vtxr1300 said:
I've followed 2 very similar tutorials on creating a windows service
and an installer. But, after successfully compiling it, I try to do
the InstallUtil command, but I get a badimageformatexception. I tried
to do some searching on that exception, but all I could find was a
small blurb on MSs site about C++ which I'm not using. Can anyone see
a problem in this code? Thanks.

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Diagnostics;

namespace FaxWatcher
{
class Stalker : IDisposable
{
#region members
private string _path = string.Empty;
private string _filter = string.Empty;
private string _savepath = string.Empty;
private string _logfile = string.Empty;
private DateTime dt = DateTime.Now;

FileSystemWatcher fsw = null;
#endregion

#region cstor
public Stalker(string stalkpath, string savepath, string
filter)
{
_path = stalkpath.Trim();
_filter = filter.Trim();
_savepath = savepath.Trim();
_logfile =
Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);

fsw = new FileSystemWatcher();
fsw.Path = _path;
fsw.Filter = _filter;
fsw.NotifyFilter = NotifyFilters.CreationTime;
fsw.EnableRaisingEvents = true;
fsw.Changed += new FileSystemEventHandler(fsw_Changed);
}
#endregion

#region directory changed event
void fsw_Changed(object sender, FileSystemEventArgs e)
{
string filepath = e.FullPath;
string filename = e.Name;
string tofolder = dt.ToShortDateString().Replace("/",
string.Empty);

if (!Directory.Exists(_savepath + "/" + tofolder))
Directory.CreateDirectory(_savepath + "/" + tofolder);

if (File.Exists(_savepath + "/" + tofolder + "/" +
filename))
GetNewFileName(ref filename, _savepath + "/" +
tofolder);

try
{
//do we need to do some renaming here?
File.Copy(filepath, _savepath + "/" + tofolder + "/" +
filename);
File.Delete(filepath);
}
#region error occurred, log to text file
catch (Exception exc)
{
try
{
Stream st = null;
if (!File.Exists(_logfile + "/log.txt"))
st = File.Create(_logfile + "/log.txt");
else
st = File.Open(_logfile + "/log.txt",
FileMode.Append);

TextWriter tw = new StreamWriter(st);
tw.WriteLine(filepath + " | " + exc.ToString());
tw.Close(); tw.Dispose();
st.Dispose(); st = null;
}
catch (Exception ex) { }
}
#endregion
}
#endregion

#region GetNewFileName
private void GetNewFileName(ref string filename, string path)
{

int i = 1;
string tmpName = filename;

while (File.Exists(path + "\\" + tmpName))
{
tmpName = String.Concat(filename.Substring(0,
filename.LastIndexOf(".")), i,
filename.Substring(filename.LastIndexOf(".")));
i++;
}

filename = tmpName;
}
#endregion

#region properties
public string StalkPath
{
set { _path = value.Trim(); }
get { return _path; }
}

public string StalkFilter
{
set { _filter = value.Trim(); }
get { return _filter; }
}
#endregion

#region cleanup
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}

protected virtual void Dispose(bool disposing)
{
if (disposing)
if (fsw != null)
fsw.Dispose(); fsw = null;
}

~Stalker()
{
Dispose(false);
}
#endregion
}
}

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

namespace FaxWatcher
{
class StalkerService : ServiceBase
{
Stalker s = null;

public StalkerService()
{
this.ServiceName = "Stalker";
this.CanStop = true;
this.CanPauseAndContinue = false;
this.AutoLog = false;
}

public static void Main()
{
System.ServiceProcess.ServiceBase.Run(new
StalkerService());

}

protected override void OnStart(string[] args)
{
if (args.Length > 2)
s = new Stalker(args[0], args[1], args[2]);
}

protected override void OnShutdown()
{
if (s != null)
s.Dispose();
base.OnShutdown();
}
}
}


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

namespace FaxWatcher
{
[RunInstaller(true)]
public class StalkerServiceInstaller : Installer
{
private ServiceProcessInstaller processInstaller;
private ServiceInstaller serviceInstaller;

public StalkerServiceInstaller()
{
processInstaller = new ServiceProcessInstaller();
serviceInstaller = new ServiceInstaller();

processInstaller.Account = ServiceAccount.LocalSystem;
serviceInstaller.StartType = ServiceStartMode.Manual;
serviceInstaller.ServiceName = "Stalker";

Installers.Add(serviceInstaller);
Installers.Add(processInstaller);
}
}
}
 
V

vtxr1300

No, I didn't create it as a windows service project type, but I
manually added all the references in that a windows service type
project adds. So, I tried again starting from scratch starting with a
service project type. I added the installer, set the properties and
tried to run the installutil again, but it still gives me the same
exception. I tried using your suggestion with the "right click in teh
Setup project..", but I'm not clear on where I should right click.
I've right clicked all over the place and I'm not seeing an "Install
service" option. Thanks for your help!
 
I

Ignacio Machin \( .NET/ C# MVP \)

Hi

vtxr1300 said:
No, I didn't create it as a windows service project type, but I
manually added all the references in that a windows service type
project adds. So, I tried again starting from scratch starting with a
service project type. I added the installer, set the properties and
tried to run the installutil again, but it still gives me the same
exception. I tried using your suggestion with the "right click in teh
Setup project..", but I'm not clear on where I should right click.
I've right clicked all over the place and I'm not seeing an "Install
service" option. Thanks for your help!

Do this,
Start a new windows service project, just add your work code, do not include
any of the install code you originally had.
right click in the designer view of the service class (service1.cs is the
default) and select "Add Installer" , set the properties of ServceInstaller1
to your preferences. , remember to set the Account property in the
ServiceProcessInstaller1 .

Now add a new project to your solution, of type "Setup project" , right
click in the project name, select Add project output and select "Primary
project output"

Right click again in the setup project and select "Add Custom Action" , a
new window appear, right click and select "Add custom action" then select
App forder, and what is next. This will add the output to the four custom
actions

Now you are ready, build the setup project, right click and select "Install"

Pd:
I typed all the above in OE , maybe some menu items are not 100% verbatim,
but you get the idea
 
V

vtxr1300

Thanks. I was able to get it to install and it appeared under
Administrative Tools>Services. I started it but it doesn't seem to be
working.

Basically what it's supposed to do is watch a folder and whenever a
word doc is saved to that folder, it's supposed to copy it over to
another folder. How do you debug a service? I went back into VS and
tried to run the service, but it said "Cannot start service from the
command line or a debugger. A Windows Service must first be installed
(using installutil.exe) and then started with the ServerExplorer,
Windows Services Administrative tool or the NET START command."

So, I'm not sure how to debug from here. When I had the watching code
in another console project, it worked great. In my service project
properties, I set up the startup object to be Program.cs which has...

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

namespace FaxWatcher
{
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 StalkerService() };

ServiceBase.Run(ServicesToRun);
}
}
}

and the StalkerService code is...

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

namespace FaxWatcher
{
public partial class StalkerService : ServiceBase
{
Stalker s = null;
public StalkerService()
{
ServiceName = "Stalker";
CanStop = true;
CanPauseAndContinue = false;
AutoLog = false;
InitializeComponent();
}

protected override void OnStart(string[] args)
{
if (args.Length > 2)
s = new Stalker(args[0], args[1], args[2]);
}

protected override void OnStop()
{
if (s != null)
s.Dispose();
base.Stop();
}

protected override void OnShutdown()
{
if (s != null)
s.Dispose();
base.OnShutdown();
}
}

}

When I start the service in Administrative Tools>Services, I do specify
start up parameters like "c:\test","c:\test2","*.doc". Thanks again
for your help. Any ideas what I might be doing wrong? Thanks.
 
G

Guest

vtxr1300,

Here is an article that shows how to create a "self-installing" service
using Craig Andera's solution, along with code to have the service run as a
regular Windows EXE (not a service) in debug mode:

http://www.eggheadcafe.com/articles/20060104.asp

Peter

--
Co-founder, Eggheadcafe.com developer portal:
http://www.eggheadcafe.com
UnBlog:
http://petesbloggerama.blogspot.com




vtxr1300 said:
Thanks. I was able to get it to install and it appeared under
Administrative Tools>Services. I started it but it doesn't seem to be
working.

Basically what it's supposed to do is watch a folder and whenever a
word doc is saved to that folder, it's supposed to copy it over to
another folder. How do you debug a service? I went back into VS and
tried to run the service, but it said "Cannot start service from the
command line or a debugger. A Windows Service must first be installed
(using installutil.exe) and then started with the ServerExplorer,
Windows Services Administrative tool or the NET START command."

So, I'm not sure how to debug from here. When I had the watching code
in another console project, it worked great. In my service project
properties, I set up the startup object to be Program.cs which has...

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

namespace FaxWatcher
{
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 StalkerService() };

ServiceBase.Run(ServicesToRun);
}
}
}

and the StalkerService code is...

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

namespace FaxWatcher
{
public partial class StalkerService : ServiceBase
{
Stalker s = null;
public StalkerService()
{
ServiceName = "Stalker";
CanStop = true;
CanPauseAndContinue = false;
AutoLog = false;
InitializeComponent();
}

protected override void OnStart(string[] args)
{
if (args.Length > 2)
s = new Stalker(args[0], args[1], args[2]);
}

protected override void OnStop()
{
if (s != null)
s.Dispose();
base.Stop();
}

protected override void OnShutdown()
{
if (s != null)
s.Dispose();
base.OnShutdown();
}
}

}

When I start the service in Administrative Tools>Services, I do specify
start up parameters like "c:\test","c:\test2","*.doc". Thanks again
for your help. Any ideas what I might be doing wrong? Thanks.
 
I

Ignacio Machin \( .NET/ C# MVP \)

HI,

Are you sure args.Count > 2 ?

With a service the tricky part is debuggin the OnStart, Use the event log
for this case.

Debugging a service is easy (except the above) you just run it form thr
services console, and then in the VS IDE select Debug/Processes ( make sure
you have Show system processes & Show processes from all users check) select
your process and select managed code only. then you can debug it.


--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation


vtxr1300 said:
Thanks. I was able to get it to install and it appeared under
Administrative Tools>Services. I started it but it doesn't seem to be
working.

Basically what it's supposed to do is watch a folder and whenever a
word doc is saved to that folder, it's supposed to copy it over to
another folder. How do you debug a service? I went back into VS and
tried to run the service, but it said "Cannot start service from the
command line or a debugger. A Windows Service must first be installed
(using installutil.exe) and then started with the ServerExplorer,
Windows Services Administrative tool or the NET START command."

So, I'm not sure how to debug from here. When I had the watching code
in another console project, it worked great. In my service project
properties, I set up the startup object to be Program.cs which has...

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

namespace FaxWatcher
{
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 StalkerService() };

ServiceBase.Run(ServicesToRun);
}
}
}

and the StalkerService code is...

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

namespace FaxWatcher
{
public partial class StalkerService : ServiceBase
{
Stalker s = null;
public StalkerService()
{
ServiceName = "Stalker";
CanStop = true;
CanPauseAndContinue = false;
AutoLog = false;
InitializeComponent();
}

protected override void OnStart(string[] args)
{
if (args.Length > 2)
s = new Stalker(args[0], args[1], args[2]);
}

protected override void OnStop()
{
if (s != null)
s.Dispose();
base.Stop();
}

protected override void OnShutdown()
{
if (s != null)
s.Dispose();
base.OnShutdown();
}
}

}

When I start the service in Administrative Tools>Services, I do specify
start up parameters like "c:\test","c:\test2","*.doc". Thanks again
for your help. Any ideas what I might be doing wrong? Thanks.
 
V

vtxr1300

Ignacio, thanks for your help. That worked perfectly. I realized I
was just specifying my start parameters incorrectly. Once those were
corrected, things moved along much smoother. However, there are now 2
problems I'm having related to the service.

1. When I start my service with the parameters, it works. However, if
the machine is rebooted and it tries to automatically start, the
parameters are missing. Is there some way to make those parameters
stay in that text field so everytime the service starts, they're there?

2. I'm using a FileSystemWatcher and supposedly, it's setup to watch
the c:\test directory for any changes or creations. It's only firing
when I save a file to the directory. When I copy a file to the
directory, it's not working. Do you know if there's some other flag I
need to set to have it work on file copying? Thanks again.
 
I

Ignacio Machin \( .NET/ C# MVP \)

Hi,

vtxr1300 said:
Ignacio, thanks for your help. That worked perfectly. I realized I
was just specifying my start parameters incorrectly. Once those were
corrected, things moved along much smoother. However, there are now 2
problems I'm having related to the service.

1. When I start my service with the parameters, it works. However, if
the machine is rebooted and it tries to automatically start, the
parameters are missing. Is there some way to make those parameters
stay in that text field so everytime the service starts, they're there?

Don't know really, what you can do is set the last used parameters in the
registry, so when you start you check your parameters, if not found go to
grab it from the registry, if not found there either use a default value or
throw an exception
2. I'm using a FileSystemWatcher and supposedly, it's setup to watch
the c:\test directory for any changes or creations. It's only firing
when I save a file to the directory. When I copy a file to the
directory, it's not working. Do you know if there's some other flag I
need to set to have it work on file copying? Thanks again.

Take a look at the differents events that you can accept with the FSW, IMO
the FSW has some issues, sometimes you get duplicated events so you have to
be careful
 

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