以编程方式安装 Windows 服务
我正在尝试通过 C# 以编程方式安装服务,但遇到了无法解决的问题。
在阅读了大量文档后,我相信微软有一个错误(但我们都知道事实并非如此)。
这是我的应用程序的Main
。
static void Main(string[] args)
{
AppDomain.CurrentDomain.UnhandledException += CurrentDomainUnhandledException;
if (System.Environment.UserInteractive)
{
string parameter = string.Concat(args);
switch (parameter)
{
case "/install":
ManagedInstallerClass.InstallHelper(new string[] { Assembly.GetExecutingAssembly().Location });
Console.Read();
break;
case "/uninstall":
ManagedInstallerClass.InstallHelper(new string[] { "/u", Assembly.GetExecutingAssembly().Location });
break;
}
}
else
{
ServiceBase.Run(new ProxyMonitor());
}
}
当在管理权限下在 CMD 中执行时,像这样 ProxyMonitor /install
,步骤进入到行:
ManagedInstallerClass.InstallHelper(new string[] { Assembly.GetExecutingAssembly().Location });
正如预期的那样,然后跳转到我的安装类,如下所示:
namespace Serco.Services.ProxyMonitor
{
[RunInstaller(true)]
public class ManagedInstallation : ServiceInstaller
{
public ManagedInstallation()
{
var ProcessInstaller = new ServiceProcessInstaller();
var ServiceInstaller = new ServiceInstaller();
//set the information and privileges
ProcessInstaller.Account = ServiceConfiguration.AccountType;
ServiceInstaller.DisplayName = ServiceConfiguration.DisplayName;
ServiceInstaller.StartType = ServiceConfiguration.StartType;
ServiceInstaller.Description = ServiceConfiguration.Description;
ServiceInstaller.ServiceName = ServiceConfiguration.ServiceName;
Installers.Add(ProcessInstaller);
Installers.Add(ServiceInstaller);
}
}
}
检查调试文件后,我得到以下内容:
Installing assembly 'C:\Users\Robert\documents\visual studio 2010\Projects\ProxyMonitor\ProxyMonitor\bin\Debug\ProxyMonitor.exe'.
Affected parameters are:
logtoconsole =
logfile = C:\Users\Robert\documents\visual studio 2010\Projects\ProxyMonitor\ProxyMonitor\bin\Debug\ProxyMonitor.InstallLog
assemblypath = C:\Users\Robert\documents\visual studio 2010\Projects\ProxyMonitor\ProxyMonitor\bin\Debug\ProxyMonitor.exe
Installing service ...
Creating EventLog source in log Application...
Rolling back assembly 'C:\Users\Robert\documents\visual studio 2010\Projects\ProxyMonitor\ProxyMonitor\bin\Debug\ProxyMonitor.exe'.
Affected parameters are:
logtoconsole =
logfile = C:\Users\Robert\documents\visual studio 2010\Projects\ProxyMonitor\ProxyMonitor\bin\Debug\ProxyMonitor.InstallLog
assemblypath = C:\Users\Robert\documents\visual studio 2010\Projects\ProxyMonitor\ProxyMonitor\bin\Debug\ProxyMonitor.exe
Restoring event log to previous state for source .
我还得到以下调用中抛出的异常:
ManagedInstallerClass.InstallHelper(new string[] { Assembly.GetExecutingAssembly().Location });
说明:
安装失败,已执行回滚。必须指定源值。
更新:
配置类
namespace Serco.Services.ProxyMonitor
{
class ServiceConfiguration
{
public static string DisplayName
{
get { return "Serco Proxy Monitor"; }
}
public static string ServiceName
{
get { return "Serco Proxy Monitor"; }
}
public static string Description
{
get
{
return "Serco ProxyMonitor is a helper developed to manage the state of the proxy for the employess whilst of the internal network.";
}
}
public static ServiceStartMode StartType
{
get{return ServiceStartMode.Automatic;}
}
public static ServiceAccount AccountType
{
get{return ServiceAccount.LocalSystem;}
}
/*.. /Snip/ ..*/
}
}
I'm attempting to install a service programmatically via C# but I have run into an issue that I can't get around.
After reading loads of documentation I'm at that point where I believe Microsoft have a bug, (But we all know that's not the case).
So here's the Main
of my application.
static void Main(string[] args)
{
AppDomain.CurrentDomain.UnhandledException += CurrentDomainUnhandledException;
if (System.Environment.UserInteractive)
{
string parameter = string.Concat(args);
switch (parameter)
{
case "/install":
ManagedInstallerClass.InstallHelper(new string[] { Assembly.GetExecutingAssembly().Location });
Console.Read();
break;
case "/uninstall":
ManagedInstallerClass.InstallHelper(new string[] { "/u", Assembly.GetExecutingAssembly().Location });
break;
}
}
else
{
ServiceBase.Run(new ProxyMonitor());
}
}
When executed within CMD under administration privileges like so ProxyMonitor /install
the step into goes down to the line:
ManagedInstallerClass.InstallHelper(new string[] { Assembly.GetExecutingAssembly().Location });
as expected, and then jumps into my install class like so:
namespace Serco.Services.ProxyMonitor
{
[RunInstaller(true)]
public class ManagedInstallation : ServiceInstaller
{
public ManagedInstallation()
{
var ProcessInstaller = new ServiceProcessInstaller();
var ServiceInstaller = new ServiceInstaller();
//set the information and privileges
ProcessInstaller.Account = ServiceConfiguration.AccountType;
ServiceInstaller.DisplayName = ServiceConfiguration.DisplayName;
ServiceInstaller.StartType = ServiceConfiguration.StartType;
ServiceInstaller.Description = ServiceConfiguration.Description;
ServiceInstaller.ServiceName = ServiceConfiguration.ServiceName;
Installers.Add(ProcessInstaller);
Installers.Add(ServiceInstaller);
}
}
}
After checking the debug file I get the following:
Installing assembly 'C:\Users\Robert\documents\visual studio 2010\Projects\ProxyMonitor\ProxyMonitor\bin\Debug\ProxyMonitor.exe'.
Affected parameters are:
logtoconsole =
logfile = C:\Users\Robert\documents\visual studio 2010\Projects\ProxyMonitor\ProxyMonitor\bin\Debug\ProxyMonitor.InstallLog
assemblypath = C:\Users\Robert\documents\visual studio 2010\Projects\ProxyMonitor\ProxyMonitor\bin\Debug\ProxyMonitor.exe
Installing service ...
Creating EventLog source in log Application...
Rolling back assembly 'C:\Users\Robert\documents\visual studio 2010\Projects\ProxyMonitor\ProxyMonitor\bin\Debug\ProxyMonitor.exe'.
Affected parameters are:
logtoconsole =
logfile = C:\Users\Robert\documents\visual studio 2010\Projects\ProxyMonitor\ProxyMonitor\bin\Debug\ProxyMonitor.InstallLog
assemblypath = C:\Users\Robert\documents\visual studio 2010\Projects\ProxyMonitor\ProxyMonitor\bin\Debug\ProxyMonitor.exe
Restoring event log to previous state for source .
I also get the exception thrown within the following call:
ManagedInstallerClass.InstallHelper(new string[] { Assembly.GetExecutingAssembly().Location });
Stating:
The installation failed, and the rollback has been performed. Must specify value for source.
Updates:
Configuration Class
namespace Serco.Services.ProxyMonitor
{
class ServiceConfiguration
{
public static string DisplayName
{
get { return "Serco Proxy Monitor"; }
}
public static string ServiceName
{
get { return "Serco Proxy Monitor"; }
}
public static string Description
{
get
{
return "Serco ProxyMonitor is a helper developed to manage the state of the proxy for the employess whilst of the internal network.";
}
}
public static ServiceStartMode StartType
{
get{return ServiceStartMode.Automatic;}
}
public static ServiceAccount AccountType
{
get{return ServiceAccount.LocalSystem;}
}
/*.. /Snip/ ..*/
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我想通了,并认为我会发布此信息以防止其他人可能遇到同样的问题。
它是几件事的组合,但我只是快速向您展示它们:
return "SercoProxyMonitor";
UnhandledException
,然后在中显示更多内容深度堆栈跟踪我认为主要问题是
ServiceInstaller
使用ServiceName
来创建EventLogSource
,并且由于EventLogSource 中存在空格
它大发雷霆。I figured it out and thought I would post encase others may be having the same issue.
It was a combination of a few things but ill just quickly show you them:
return "SercoProxyMonitor";
due to the spacesUnhandledException
which then showed more in depth stack tracesI think the main issue was that the
ServiceInstaller
was using theServiceName
to create andEventLogSource
, And as there were spaces within theEventLogSource
it was throwing a fit.看起来日志源为空;您确定
ServiceConfiguration.ServiceName
已定义并且具有值吗?It looks like the log source is null; are you sure that
ServiceConfiguration.ServiceName
is defined and has a value?