以编程方式安装 Windows 服务

发布于 2024-10-14 22:33:20 字数 4078 浏览 3 评论 0原文

我正在尝试通过 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

柳若烟 2024-10-21 22:33:20

我想通了,并认为我会发布此信息以防止其他人可能遇到同样的问题。

它是几件事的组合,但我只是快速向您展示它们:

public static string ServiceName
{
    get { return "Serco Proxy Monitor"; }
}
  • 由于空格,必须变成 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:

public static string ServiceName
{
    get { return "Serco Proxy Monitor"; }
}
  • Had to become return "SercoProxyMonitor"; due to the spaces
  • Removed the UnhandledException which then showed more in depth stack traces
  • Needed to have Full Administrator Rights.

I think the main issue was that the ServiceInstaller was using the ServiceName to create and EventLogSource, And as there were spaces within the EventLogSource it was throwing a fit.

任谁 2024-10-21 22:33:20

看起来日志源为空;您确定 ServiceConfiguration.ServiceName 已定义并且具有值吗?

It looks like the log source is null; are you sure that ServiceConfiguration.ServiceName is defined and has a value?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文