我目前正在开发一个带有.Net 3.5目标的Windows服务。
我遇到了很多问题:
虽然我在解决方案中有一个安装项目,但即使安装程序成功完成,它也会安装该服务(平台是vista)。 我必须使用位于.Net 2.0文件夹而不是3.5文件夹中的InstallUtil.exe手动安装服务。
我无法使用ConfigrationManager对象访问app.config。我怀疑这是因为正在运行的服务不是从它的安装目录运行的。有没有人知道我在运行时安全地访问它的方法?
非常感谢有关此主题的任何建议和经验。
詹姆斯
答案 0 :(得分:3)
我最近自己做了这个,这里的代码允许你传递“/ install”或“/ uninstall”作为命令行选项来安装你的服务。如果您愿意,可以将其更改为自动安装。它还可以访问app.config(我的原始服务在其主循环中执行此操作)。如您所见,我将其设置为以特定用户身份运行,但您可以设置spi.Account = ServiceAccount.LocalSystem;并省略名称和密码。希望这会有所帮助:
namespace MyService
{
public class ServiceMonitor : ServiceBase
{
private System.ComponentModel.Container _components = null;
private static string _service_name = "MyServiceName";
public ServiceMonitor()
{
InitializeComponent();
}
private void InitializeComponent()
{
this.CanHandlePowerEvent = true;
this.CanPauseAndContinue = true;
this.CanShutdown = true;
this.CanStop = true;
this.ServiceName = _service_name;
}
protected override void Dispose(bool disposing)
{
if (disposing && _components != null)
{
_components.Dispose();
}
base.Dispose(disposing);
}
static void Main(string[] args)
{
string opt = null;
if (args.Length >= 1)
{
opt = args[0].ToLower();
}
if (opt == "/install" || opt == "/uninstall")
{
TransactedInstaller ti = new TransactedInstaller();
MonitorInstaller mi = new MonitorInstaller(_service_name);
ti.Installers.Add(mi);
string path = String.Format("/assemblypath={0}", Assembly.GetExecutingAssembly().Location);
string[] cmdline = { path };
InstallContext ctx = new InstallContext("", cmdline);
ti.Context = ctx;
if (opt == "/install")
{
Console.WriteLine("Installing");
ti.Install(new Hashtable());
}
else if (opt == "/uninstall")
{
Console.WriteLine("Uninstalling");
try
{
ti.Uninstall(null);
}
catch (InstallException ie)
{
Console.WriteLine(ie.ToString());
}
}
}
else
{
ServiceBase[] services;
services = new ServiceBase[] { new ServiceMonitor() };
ServiceBase.Run(services);
}
}
protected override void OnStart(string[] args)
{
//
// TODO: spawn a new thread or timer to perform actions in the background.
//
base.OnStart(args);
}
protected override void OnStop()
{
//
// TODO: stop your thread or timer
//
base.OnStop();
}
}
[RunInstaller(true)]
public class MonitorInstaller : Installer
{
public MonitorInstaller()
: this("MyServiceName")
{
}
public MonitorInstaller(string service_name)
{
ServiceProcessInstaller spi = new ServiceProcessInstaller();
spi.Account = ServiceAccount.User;
spi.Password = ConfigurationManager.AppSettings["Password"];
spi.Username = ConfigurationManager.AppSettings["Username"];
ServiceInstaller si = new ServiceInstaller();
si.ServiceName = service_name;
si.StartType = ServiceStartMode.Automatic;
si.Description = "MyServiceName";
si.DisplayName = "MyServiceName";
this.Installers.Add(spi);
this.Installers.Add(si);
}
}
}
答案 1 :(得分:2)
安装服务需要在安装项目中创建自定义操作,否则无法注册。
答案 2 :(得分:1)
正如其他人所说,你必须创建一个安装项目来进行安装。我还写了batch个文件,没有设置就可以了。
有关创建安装项目的帮助,我发现以下链接很有帮助。
How to create a setup project for a Windows Service application in Visual C#
Windows Services in C#: Part 2: Adding an Installer for Your Windows Service
答案 3 :(得分:0)