前段时间,我写了一篇描述了如何为WinForms应用程序创建项目模板的博客。这篇博客描述了一个新的项目模板:提供了用F# 创建Windows Service程序需要的元素。你可以在Visual Studio Gallery里找到这个模板:
http://visualstudiogallery.msdn.microsoft.com/1f2ee1da-e87f-4863-b98e-d8b7b63d2253
安装完此模板后,你会在创建F#项目时看到如下图所示的模板已经被加入到F# 文件夹中了:
这个模板提供了多个项目元素:
- 一个MyService.fs和Program.fs源文件提供服务元素
- 一个Installer.fs源文件实现了利用安装工具安装此服务的功能
- 一个安转与卸载此服务的命令文件
这个MyService.fs源文件提供了此服务的实现。这个模板代码为OnStart和OnStop方法提供了框架已经展示了如何创建一个EventLog和如何引用此EventLog。
namespace FSharp.Service
open System;
open System.Diagnostics;
open System.Linq;
open System.ServiceProcess;
open System.Text;
type public MyService() as service =
inherit ServiceBase()
// TODO define your service variables
let eventLog = new EventLog();
// TODO initialize your service
let initService =
service.ServiceName <- "FSharp.Service"
// Define the Event Log
let eventSource = "FSharp.Service"
if not (EventLog.SourceExists(eventSource)) then
EventLog.CreateEventSource(eventSource, "Application");
eventLog.Source <- eventSource;
eventLog.Log <- "Application";
do
initService
// TODO define your service operations
override service.OnStart(args:string[]) =
base.OnStart(args)
eventLog.WriteEntry( "Service Started")
override service.OnStop() =
base.OnStop()
eventLog.WriteEntry( "Service Ended")
open System;
open System.Diagnostics;
open System.Linq;
open System.ServiceProcess;
open System.Text;
type public MyService() as service =
inherit ServiceBase()
// TODO define your service variables
let eventLog = new EventLog();
// TODO initialize your service
let initService =
service.ServiceName <- "FSharp.Service"
// Define the Event Log
let eventSource = "FSharp.Service"
if not (EventLog.SourceExists(eventSource)) then
EventLog.CreateEventSource(eventSource, "Application");
eventLog.Source <- eventSource;
eventLog.Log <- "Application";
do
initService
// TODO define your service operations
override service.OnStart(args:string[]) =
base.OnStart(args)
eventLog.WriteEntry( "Service Started")
override service.OnStop() =
base.OnStop()
eventLog.WriteEntry( "Service Ended")
此程序的如可被定义在Program.fs源文件中:
namespace FSharp.Service
open System
open System.Collections.Generic
open System.Linq
open System.ServiceProcess
open System.Text
module Program =
[<EntryPoint>]
let Main(args) =
// Define your services
let myService = new MyService()
// Start the services
let servicesToRun = [| myService :> ServiceBase |]
ServiceBase.Run(servicesToRun)
// main entry point return
0
open System
open System.Collections.Generic
open System.Linq
open System.ServiceProcess
open System.Text
module Program =
[<EntryPoint>]
let Main(args) =
// Define your services
let myService = new MyService()
// Start the services
let servicesToRun = [| myService :> ServiceBase |]
ServiceBase.Run(servicesToRun)
// main entry point return
0
如上所示,一个服务的入口是用[<EntryPoing>]属性来定义的。
最后,为了让安装工具能正确安装此服务,一个名为Installer的类被定义如下所示:
namespace FSharp.Service
open System
open System.Configuration
open System.Configuration.Install
open System.ComponentModel
open System.Linq
open System.ServiceProcess
[<RunInstaller( true)>]
type public ProjectInstaller() as installer =
inherit Installer()
let processInstaller = new ServiceProcessInstaller();
let serviceInstaller = new ServiceInstaller();
// TODO initialize your service
let initInstaller =
// Define the process settings
processInstaller.Account <- ServiceAccount.LocalSystem
processInstaller.Password <- null
processInstaller.Username <- null
// Define the service settings
serviceInstaller.Description <- "FSharp.Service MyService"
serviceInstaller.ServiceName <- "FSharp.Service.MyService"
serviceInstaller.StartType <- ServiceStartMode.Manual;
// Define the installers
let installers = [| processInstaller :> Installer; serviceInstaller :> Installer|]
installer.Installers.AddRange(installers)
do
initInstaller
open System
open System.Configuration
open System.Configuration.Install
open System.ComponentModel
open System.Linq
open System.ServiceProcess
[<RunInstaller( true)>]
type public ProjectInstaller() as installer =
inherit Installer()
let processInstaller = new ServiceProcessInstaller();
let serviceInstaller = new ServiceInstaller();
// TODO initialize your service
let initInstaller =
// Define the process settings
processInstaller.Account <- ServiceAccount.LocalSystem
processInstaller.Password <- null
processInstaller.Username <- null
// Define the service settings
serviceInstaller.Description <- "FSharp.Service MyService"
serviceInstaller.ServiceName <- "FSharp.Service.MyService"
serviceInstaller.StartType <- ServiceStartMode.Manual;
// Define the installers
let installers = [| processInstaller :> Installer; serviceInstaller :> Installer|]
installer.Installers.AddRange(installers)
do
initInstaller
这个版本的模板使用本地帐户来创建此服务。但是,修改帐户是很简单的。
最后,这个模板创建一个用来安装和卸载此服务的命令文件。当运行此命令文件时,你需要一个较高的权限来运行此命令。
另外,但愿此模板对你有所帮助。