【问题标题】:Easiest language for creating a Windows service创建 Windows 服务的最简单语言
【发布时间】:2010-10-10 06:10:23
【问题描述】:

构建 Windows 服务最简单的语言是什么?

在这种情况下,最简单的定义是代码量最少,进入语言的最低点。

【问题讨论】:

    标签: windows-services


    【解决方案1】:

    冒着明显的风险,如果你有任何 C/C++/Java 背景,我认为 C# 为你提供了最低的入门点。

    假设您使用的是 Visual Studio 2008,您可以按照以下步骤操作:

    1. 打开 Visual Studio 2008,然后选择 File|New|Project 菜单选项。
    2. 在“新建项目”对话框中...
      • 在项目类型中选择 Visual C#|Windows 节点
      • 选择 Windows 服务模板
      • 输入项目的名称和位置
      • 按确定
    3. 至此,您已经掌握了 Windows 服务的所有基础知识。 Program.cs 文件包含服务的 Main() 方法,Service1.cs 定义 System.ServiceProcess.ServiceBase 组件,它是您的新 Windows 服务。
    4. 在 Service1 组件的属性网格中,考虑至少设置以下属性:
      • (名称)- 给您的对象一个直观的名称,例如,ServiceExample
      • AutoLog - 设置为 false 以防止默认情况下将事件写入应用程序事件日志(注意:我并不是说您不应该记录服务事件;我只是更喜欢写入自己的事件日志而不是应用程序日志 - 见下文)
      • CanShutdown - 如果您想处理系统关闭,请设置为 true
      • ServiceName - 定义服务控制管理器 (SCM) 知道您的服务的名称
    5. 在 ServiceExample 的代码中,OnStart() 和 OnStop() 虚函数被删除。您需要用您的服务显然需要做的任何事情来填写这些内容。如果您将 CanShutdown 属性更改为 true,您还需要覆盖 OnShutdown 方法。我在下面创建了一个示例来说明这些函数的使用。
    6. 至此,ServiceExample 服务基本完成,但您仍需要一种方法来安装它。为此,请在设计器中打开 ServiceExample 组件。右键单击设计器面板中的任意位置,然后选择“添加安装程序”菜单选项。这会向您的项目添加一个 ProjectInstaller 组件,其中包含两个附加组件 - serviceProcessInstaller1 和 serviceInstaller1。
    7. 在设计器中选择 serviceProcessInstaller1 组件。在属性网格中,考虑设置以下属性:
      • (名称)- 给您的对象一个直观的名称,例如 serviceProcessInstaller
      • 帐户 - 至少选择 LocalService 帐户,但如果您的服务需要更多权限,您可能必须使用 NetworkService 或 LocalSystem 帐户
    8. 在设计器中选择 serviceInstaller1 组件。在属性网格中,考虑设置以下属性:
      • (名称)- 为您的对象提供直观的名称,例如 serviceInstaller
      • 描述 - 服务描述,将显示在您的服务的 SCM 中
      • DisplayName - 您的服务的友好名称,将显示在您的服务的 SCM 中
      • ServiceName - 确保该名称与您为 ServiceExample 组件的 ServiceName 属性选择的名称相同(参见步骤 4)
      • StartType - 指明您希望服务自动启动还是手动启动
    9. 请记住,我说过我更喜欢将事件写入我自己的事件日志而不是应用程序事件日志。为此,您需要将 ProjectInstaller 中的默认 EventLogInstaller 替换为自定义的。使您的 ProjectInstaller 代码如下所示:

    using System.Diagnostics;
    [RunInstaller(true)]
    public partial class ProjectInstaller : Installer
    {
        public ProjectInstaller()
        {
            InitializeComponent();
    
            EventLogInstaller installer = FindInstaller(this.Installers);
            if (installer != null)
            {
                installer.Log = "ServiceExample"; // enter your event log name here
            }
        }
    
        private EventLogInstaller FindInstaller(InstallerCollection installers)
        {
            foreach (Installer installer in installers)
            {
                if (installer is EventLogInstaller)
                {
                    return (EventLogInstaller)installer;
                }
    
                EventLogInstaller eventLogInstaller = FindInstaller(installer.Installers);
                if (eventLogInstaller != null)
                {
                    return eventLogInstaller;
                }
            }
            return null;
        }
    }
    

    此时,您可以构建项目以获取 Windows 服务可执行文件。要安装您的服务,请打开 Visual Studio 2008 命令提示符,然后导航到可执行文件所在的 Debug 或 Release 目录。在命令提示符处,键入以下内容:InstallUtil ServiceExample.exe。这将在本地机器上安装您的服务。要卸载它,请在命令提示符处键入以下内容:InstallUtil /u ServiceExample.exe

    只要您的服务没有运行,您就可以对您的服务进行更改并重新构建,也就是说,您不必卸载您的服务来对其进行更改。但是,只要它正在运行,您就无法用您的修复和增强功能覆盖该可执行文件。

    要查看您的服务的运行情况,请打开 ServiceExample.cs 文件并进行以下更改:

    using System.Diagnostics;
    public partial class ServiceExample : ServiceBase
    {
        public ServiceExample()
        {
            // Uncomment this line to debug the service.
            //Debugger.Break();
    
            InitializeComponent();
    
            // Ties the EventLog member of the ServiceBase base class to the
            // ServiceExample event log created when the service was installed.
            EventLog.Log = "ServiceExample";
        }
    
        protected override void OnStart(string[] args)
        {
            EventLog.WriteEntry("The service was started successfully.", EventLogEntryType.Information);
        }
    
        protected override void OnStop()
        {
            EventLog.WriteEntry("The service was stopped successfully.", EventLogEntryType.Information);
        }
    
        protected override void OnShutdown()
        {
            EventLog.WriteEntry("The service was shutdown successfully", EventLogEntryType.Information);
        }
    }
    

    使用这些更改运行服务后,您可以在事件查看器中查看 ServiceExample 事件日志并查看其中记录的消息。

    希望这会有所帮助。

    编辑:如果您更喜欢使用应用程序事件日志而不是自定义事件日志记录,只需不更改 ProjectInstaller.cs 文件。此外,省略在 ServiceExample 构造函数中设置 EventLog 的 Log 属性的行。当您运行服务时,您的日志消息将出现在应用程序事件日志中。

    【讨论】:

    • 要让服务从命令行自行安装,而不必使用 InstallUtil.exe,请参阅我的帖子:stackoverflow.com/questions/1195478/…
    • 如何从服务导出类/接口并从客户端(本地系统服务)调用?
    • @sarat,看看我的回复:stackoverflow.com/questions/1773046/…
    • System.UnauthorizedAccessException: Access to the path 'C:\MyService.InstallState' is denied. 原来你必须运行 cmd.exe以管理员身份运行
    • +1 这对我也有用,尤其是自定义日志的第 9 步,我还让安装程序编写了第一个条目。类似问题的许多其他答案都说要使用 WiX,但此解决方案不需要它。比 MSDN 更有帮助,并且仅在安装期间需要管理员权限。
    【解决方案2】:

    我同意所有在其他地方做出回应的人的观点,但我想说不要过多关注实际语言,只要您在 .NET 框架中工作,并且有一个适合您的入门项目,您就可以了。重新出发。我过去做过几个“Windows 服务”,并且用 VB.NET 和 C# 都用最少的代码开发了它们。

    我建议 OP 做的是学习如何为其构建安装程序包。安装该服务就像执行“installutil.exe {drive}\path\to\file.exe”一样简单,但是当您必须做比部署“hello world”Windows 服务更大的事情时,最好了解并了解如何以有意义的方式部署服务。

    不要引发一场激烈的战争,但我已经“标准化”了在我所有的部署包中使用WiX,除了做老式的 COM 互操作类型的东西,因为要正确安装这是一项首当其冲的工作.我渴望 WiX 团队开发引导程序,允许您将先决条件和主 msi 放入可以下载的 EXE 文件中。他们预定 3.5 版本,所以我会耐心等待,暂时使用 WinZip 自解压可执行文件。

    【讨论】:

    • 哇!这是一个旧帖子。我最终学习了如何使用 Heat.exe 并提取了我需要使用 WiX 和启用了 com 互操作的库的位。
    【解决方案3】:

    对我来说,我只尝试了几种方法,Visual Studio 和 C# 是最简单的。

    Visual Studio 为框架完成了所有必要的服务管道设置,我发现 C# 非常容易学习,从 VB6、VB.NET 和 C 迁移而来。

    【讨论】:

      【解决方案4】:

      使用 Visual C#,您将在网上找到最多的代码示例。 与 Visual Studio 结合使用,只需在公园中散步即可启动并运行基本的 Windows 服务。 Visual Studio 还可以轻松创建 MSI 安装程序包。

      那是我的选择

      【讨论】:

        【解决方案5】:

        C# 中的 Windows 服务项目将通过单击按钮为您提供来自 Visual Studio 模板的完全可部署的服务。您只需要添加您的有效负载代码。

        【讨论】:

          【解决方案6】:

          使用 Visual Studio Service 类型的项目,使用 C# 或 VB.NET。

          我个人更喜欢 C#,但总的来说它很容易理解生命周期并在所需阶段编写逻辑代码。

          构建安装程序也很容易。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-11-02
            • 1970-01-01
            • 2011-05-02
            • 1970-01-01
            • 1970-01-01
            • 2019-02-02
            • 1970-01-01
            • 2017-02-19
            相关资源
            最近更新 更多