【问题标题】:Error Installing a Windows Service (in F#)安装 Windows 服务时出错(在 F# 中)
【发布时间】:2015-09-23 06:26:07
【问题描述】:

我的问题如下: 当我尝试安装我的 Windows 服务时,我收到以下错误:

sn-p: ... No public installers with the RunInstallerAttribute.Yes attribute could be found in the <path to exe> assembly. ...

我关注这个tutorial

我有一个Program.fs 文件,其中包含:

[<RunInstaller(true)>]
type public FSharpServiceInstaller() =
    inherit Installer()
    do
        < some logic, doesn't really matter >

这应该足够了,事实上,我什至认为我不需要在类型定义中添加public关键字。使用InstallUtil.exe 安装这个可执行文件给了我与使用以下代码安装它相同的错误:

[<EntryPoint>]
let main args =

    if Environment.UserInteractive then
        let parameter = String.Concat(args);
        match parameter with
        | "-i" -> ManagedInstallerClass.InstallHelper [| Assembly.GetExecutingAssembly().Location |]
        | "-u" -> ManagedInstallerClass.InstallHelper [| "/u"; Assembly.GetExecutingAssembly().Location |]
        | _ -> printf "Not allowed!\n" 
    else 
        ServiceBase.Run [| new CreditToolsService() :> ServiceBase |];
    0

我尝试以管理员和我的普通帐户在 PowerShell、cmd 和 Visual Studio CLI 中运行此脚本,但我一直收到相同的错误。如果有人知道我做错了什么,我将非常感谢一些帮助。

【问题讨论】:

  • 感谢您的评论,非常感谢。我已经检查了相关问题,尽管操作员提出“相同”的问题,但没有答案;只是一个实现示例。

标签: f# windows-services service-installer


【解决方案1】:

好的,那就这样吧……

我查看了 user1758475 提供的代码,只是随机开始将粘贴解决方案复制到应用程序中。 Don Symes 的解决方案“刚刚奏效”,我终于明白了原因:我的源代码中没有(他确实)有命名空间声明。看来这才是罪魁祸首!添加命名空间后,安装程序的工作就像一个魅力。

正如 Curt Nichols 指出的,安装程序不应该在模块中,因为模块有效地隐藏了调用代码的类型。

感谢您帮助解决这个问题。

对于那些想看一个工作示例的人:

namespace FileWatcher
open System
open System.Reflection
open System.ComponentModel
open System.Configuration.Install
open System.ServiceProcess
open System.IO
open System.Configuration

type FileWatcherService() =
    inherit ServiceBase(ServiceName = "FileWatcher")

    let createEvent = fun (args: FileSystemEventArgs) -> 
                    printf "%s has been %s\n" args.FullPath (args.ChangeType.ToString().ToLower()) 
                    |> ignore

    override x.OnStart(args) =
        let fsw = new FileSystemWatcher ()
        fsw.Path                    <- "C:\TEMP"
        fsw.NotifyFilter            <- NotifyFilters.LastAccess ||| NotifyFilters.LastWrite ||| NotifyFilters.FileName ||| NotifyFilters.DirectoryName ||| NotifyFilters.CreationTime
        fsw.Filter                  <- "*.txt"
        fsw.EnableRaisingEvents     <- true
        fsw.IncludeSubdirectories   <- true
        fsw.Created.Add(createEvent)

    override x.OnStop() =
        printf "Stopping the FileWatcher service"

[<RunInstaller(true)>]
type public FSharpServiceInstaller() =
    inherit Installer()
    do 

        // Specify properties of the hosting process
        new ServiceProcessInstaller
            (Account = ServiceAccount.LocalSystem)
        |> base.Installers.Add |> ignore

        // Specify properties of the service running inside the process
        new ServiceInstaller
            ( DisplayName = "AAA FileWatcher Service", 
            ServiceName = "AAAFileWatcherService",
            StartType = ServiceStartMode.Automatic )
        |> base.Installers.Add |> ignore


module Program =
    [<EntryPoint>]
    let main args =

        printf "starting the application...\n"


        if Environment.UserInteractive then
            let parameter = String.Concat(args);
            match parameter with
            | "-i" -> ManagedInstallerClass.InstallHelper [| Assembly.GetExecutingAssembly().Location |]
            | "-u" -> ManagedInstallerClass.InstallHelper [| "/u"; Assembly.GetExecutingAssembly().Location |]
            | _ -> printf "Not allowed!\n" 
        else 
            ServiceBase.Run [| new FileWatcherService() :> ServiceBase |];
        0

【讨论】:

  • 另外——不要将服务安装程序类型放在模块中,这会有效地将其隐藏在查找它的代码中。
【解决方案2】:

https://github.com/zbilbo/TB4TG/blob/master/TourneyBot.Service/Installer.fs的工作现场制作示例

认为它需要与 InstallUtil.exe 一起安装。

可能不是编码中最好的时刻,但特定的服务代码或多或少来自 Don Syme:http://blogs.msdn.com/b/dsyme/archive/2011/05/31/a-simple-windows-service-template-for-f.aspx,所以它可能没问题,但该存储库上的其余“周围”代码可能不是惯用的;-)

Don Symes 博客还解释了更多内容,因此应该很容易适应您的需求。它还链接到 VS Gallery 上的 Win 服务模板:http://blogs.msdn.com/b/mcsuksoldev/archive/2011/05/31/f-windows-application-template-for-windows-service.aspx

【讨论】:

  • 感谢您的发帖,但我似乎无法在提供的代码链接中找到解决问题的方法。我正在尝试使用InstallUtil.exe 和我的自定义安装程序安装服务,两者都给我同样的错误。似乎安装程序找不到具有 属性的 Installer 类,尽管我在代码中明确指定了此属性
  • 如果其他示例有效而您的无效,那么 Occam 会告诉我有问题。可能假设您正在按照示例显示的内容进行操作,这是错误的。退后一步,重新开始,照原样做示例,如果它不起作用,发送电子邮件给 Thomas Petricek 或在这里调用他,并告诉他他的代码是错误的。他不时在这里;-)
  • 感谢您的帮助。我已经想出了如何解决这个问题。好像我错过了命名空间声明。我已经在答案中发布了我的代码和解决方案。
  • 所以我的回答/评论是正确的,但没有像“这很有用”这样的实际确认......好吧,我会记住的 ;-) 很好,不过你已经成功了。
  • 说实话,但评论中的第一行实际上是:“但我似乎无法在提供的代码链接中找到解决我的问题的方法”说“退后一步重新开始"在遇到问题时总是很好的建议,但不够具体以至于不能投票对吗?
猜你喜欢
  • 2018-04-08
  • 2012-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-24
  • 2017-09-27
  • 2011-01-13
  • 2016-03-14
相关资源
最近更新 更多