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

55

哪种语言最适合用于构建Windows服务?

在这种情况下,“最易”被定义为编写代码的最少量和进入该语言的最低门槛。

6个回答

186

显而易见的是,如果你具备C/C++/Java背景,我认为C#提供了最低的入门点。

假设你正在使用Visual Studio 2008,你可以按照以下步骤操作:

  1. 打开Visual Studio 2008,选择“文件|新建|项目”菜单选项。
  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
    • Account - 至少选择LocalService帐户,但如果您的服务需要更多特权,则可能必须使用NetworkService或LocalSystem帐户
  8. 在设计器中选择serviceInstaller1组件。在属性网格中,至少考虑设置以下属性:
    • (名称) - 给您的对象一个直观的名称,例如serviceInstaller
    • Description - 服务的描述将显示在服务控制管理器中
    • DisplayName - 您的服务的友好名称将显示在服务控制管理器中
    • 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属性的行。当您运行服务时,您的日志消息将出现在应用程序事件日志中。


5
若想让该服务自动安装而无需使用InstallUtil.exe,可参考我在此处发布的帖子:https://dev59.com/XHM_5IYBdhLWcg3w3nNs#1195621 - Matt Davis
3
“System.UnauthorizedAccessException: Access to the path 'C:\MyService.InstallState' is denied.”的意思是“无权访问路径'C:\MyService.InstallState'”。结果表明您需要以管理员身份运行cmd.exe,方法是:右键点击cmd.exe,选择“以管理员身份运行” - JohnB
Service1组件有一些折叠的源代码,因此重置Service1的名称不是很直观。展开Service1.cs > 展开Service1.Designer.cs > 展开代码块“Component Designer generated code”> 更新this.ServiceName =“Service1”。 - Entree
@indusBull,使用Windows事件查看器。从开始菜单中搜索“eventvwr”,然后在“应用程序和服务日志”下查找。 - Matt Davis
我知道这是老代码了,感谢 @Matt-Davis 的出色解释(+1),但我想补充一下,你可以将 FindInstaller() 方法转化为一行代码。如果你加入 using System.Linq;,在 ProjectInstaller() 中只需这么写:EventLogInstaller installer = this.Installers.Cast<Installer>().FirstOrDefault( eli => eli is EventLogInstaller ) as EventLogInstaller; if( installer != null ) installer.Log = "ServiceExample"; 这只是我的个人建议。 - Meloviz
显示剩余4条评论

4
我同意其他人的回复,但是我认为不要过于关注实际使用的编程语言,只要您在.NET框架中工作,并且有一个适合您的起始项目,您就可以开始了。我以前用VB.NET和C#开发过几个“Windows服务”,并且代码很少。
我建议OP学习如何构建安装程序包。安装服务只需执行“installutil.exe {drive} \ path \ to \ file.exe”,但是当您需要部署大于“hello world” Windows服务时,最好知道和理解如何以有意义的方式部署服务。

不是要引发争端,但我已经“标准化”使用WiX来制作所有的部署包,除了做老式的COM互操作类型的东西,因为这需要很多工作才能正确安装。我渴望WiX团队开发启动器部分,使您可以将前提条件和主要MSI放入可下载的EXE文件中。他们将其列入3.5计划,所以我会耐心等待,并暂时使用WinZip自解压执行文件。


1
哇!这是一篇旧帖子。我最终学会了如何使用Heat.exe并提取所需的位,以便将WiX与启用COM互操作的库一起使用。 - Richard B

0

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

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


0

使用Visual C#,您可以在网络上找到最多的代码示例。 结合Visual Studio,创建基本的Windows服务轻而易举。 Visual Studio还可以轻松创建MSI安装程序包。

这将是我的选择。


0

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

我个人更喜欢C#,但通常很容易理解生命周期并在所需阶段编写逻辑。

构建安装程序也非常容易。


0
通过C#创建一个Windows服务项目,你可以在Visual Studio模板中轻松地一键完成完整的可部署服务。你只需要添加你自己的有效载荷代码即可。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接