【问题标题】:How can I install my windows service on a server so that it runs in the background on startup?如何在服务器上安装我的 Windows 服务,以便它在启动时在后台运行?
【发布时间】:2015-09-28 14:01:02
【问题描述】:

我有一个我上周编写的 Windows 服务,它的目的是运行一个计时器来定期检查日期是否已更改,如果是,它会启动一个从我们的 SQL 服务器获取对象以及它们是否与当前匹配的方法日期它将它们发送到另一个处理付款的服务。我是服务新手,不确定如何安装它以使其 a) 在后台无休止地运行 b) 在服务器重置的情况下在启动时运行。

这是我在 VB.NET 中的 Windows 服务的代码

Imports System.ServiceProcess

导入 AFI.BusinessObjects.Billing 导入 System.Data.SqlClient

公共类 FutureTransactionProcessor

'Creates a timer that can't be grabbed up by garbage collection
Private Timer As System.Timers.Timer

'Create a variable for todays date minus one to check against and see if the date has advanced.
Private lastRun As DateTime = DateTime.Now.AddDays(-1)

Protected Overrides Sub OnStart(ByVal args() As String)
    ' Add code here to start your service. This method should set things
    ' in motion so your service can do its work.

    'Timer that finishes its run every 10 minutes
    Timer = New System.Timers.Timer(10 * 60 * 1000)

    'we trigger a method as soon as the timer has finished running its course
    'Timer.Elapsed += New System.Timers.ElapsedEventHandler(AddressOf timerElapsed)
    AddHandler Timer.Elapsed, AddressOf timerElapsed

    'start our timer
    Timer.Start()

End Sub

Protected Sub timerElapsed(ByVal sender As Object, e As System.Timers.ElapsedEventArgs)

    If lastRun.Date < DateTime.Now.Date Then

        'stop the timer to perform our check against the FUTURE_TRANSACTIONS table
        Timer.Stop()

        'BEGIN FUNCTION TO RETURN FUTURE TRANSACTIONS FROM FUTURE_TRANSACTION TABLE THAT MATCH TODAYS DATE IF ANY
        GetFutureTransactionsByDate(DateTime.Now.Date)


        'reset our lastRun variable so we'll know when this method was last ran
        lastRun = DateTime.Now

        'restart our timer
        Timer.Start()

    End If


End Sub

Public Shared Function GetFutureTransactionsByDate(ByVal dateToday As DateTime) As FuturePaymentsCollection

    Dim FuturePaymentsToBeProcessed As FuturePaymentsCollection = New FuturePaymentsCollection

    Using cnSQL As SqlConnection = New SqlConnection(AFI.Configuration.SystemSetting.Collection("ClientServer", "CS_Connection_String").SettingValue)

        Using cmdSP As New SqlCommand("PROC_FUTURE_TRANSACTIONS_SEL_BY_TODAY", cnSQL)

            cmdSP.CommandType = System.Data.CommandType.StoredProcedure
            cmdSP.Parameters.AddWithValue("DATETODAY", dateToday)

            cmdSP.Connection.Open()
            Dim sqlReader As SqlDataReader = cmdSP.ExecuteReader()

            If sqlReader.HasRows Then
                While (sqlReader.Read())
                    Dim futurePayment As FuturePayment = New FuturePayment

                    futurePayment.FutureTransactionID = sqlReader.GetInt32(sqlReader.GetOrdinal("BMW_TRANSACTION_ID"))
                    futurePayment.GroupID = sqlReader.GetInt32(sqlReader.GetOrdinal("BMW_CNTC_GROUP_ID"))
                    futurePayment.PayorAccountID = sqlReader.GetInt32(sqlReader.GetOrdinal("BMW_PAYOR_ACCOUNT_ID"))
                    futurePayment.PolicyID = sqlReader.GetInt32(sqlReader.GetOrdinal("BMW_POLICY_ID"))
                    futurePayment.AccountTypeID = sqlReader.GetInt32(sqlReader.GetOrdinal("BMW_ACCOUNT_TYPE_ID"))
                    futurePayment.TransationTypeID = sqlReader.GetInt32(sqlReader.GetOrdinal("BMW_TRANSACTION_TYPE_ID"))
                    futurePayment.TransactionDate = sqlReader.GetDateTime(sqlReader.GetOrdinal("BMW_TRANSACTION_DATE")).ToString("MM/dd/yyyy")
                    futurePayment.TransactionSubmitter = sqlReader.GetInt32(sqlReader.GetOrdinal("BMW_TRANSACTION_SUBMITTER"))
                    futurePayment.TransactionAmount = sqlReader.GetDecimal(sqlReader.GetOrdinal("BMW_TRANSACTION_AMOUNT"))
                    futurePayment.TransactionLast4 = sqlReader.GetString(sqlReader.GetOrdinal("BMW_TRANSACTION_LAST4"))
                    futurePayment.TransactionEmail = sqlReader.GetString(sqlReader.GetOrdinal("BMW_TRANSACTION_EMAIL"))
                    futurePayment.PaymentInfo1 = sqlReader.GetString(sqlReader.GetOrdinal("PaymentInfo1"))
                    futurePayment.PaymentInfo2 = sqlReader.GetString(sqlReader.GetOrdinal("PaymentInfo2"))
                    futurePayment.PaymentInfo3 = sqlReader.GetString(sqlReader.GetOrdinal("PaymentInfo3"))
                    futurePayment.PaymentInfo4 = sqlReader.GetString(sqlReader.GetOrdinal("PaymentInfo4"))
                    futurePayment.PaymentInfo5 = sqlReader.GetString(sqlReader.GetOrdinal("PaymentInfo5"))
                    futurePayment.PaymentInfo6 = sqlReader.GetString(sqlReader.GetOrdinal("PaymentInfo6"))
                    futurePayment.TransactionUpdateDate = sqlReader.GetDateTime(sqlReader.GetOrdinal("BMW_TRANSACTION_UPDATE_DATE"))


                    FuturePaymentsToBeProcessed.Add(futurePayment)

                End While
            End If

            cmdSP.Connection.Close()

        End Using

    End Using


    'Return us a collection of FuturePayment Items
    Return FuturePaymentsToBeProcessed


    'For every item returned we need to turn it into a OneTimePayment object
    For Each Payment As FuturePayment In FuturePaymentsToBeProcessed

        Dim PaymentToBeProcessed As OneTimePayment

        PaymentToBeProcessed.PayorAccountId = Payment.PayorAccountID
        PaymentToBeProcessed.PolicyID = Payment.PolicyID
        PaymentToBeProcessed.AccountTypeID = Payment.AccountTypeID

        'Future payments can only be EFT so we'll go ahead and set that to 1
        PaymentToBeProcessed.PayTypeID = 1
        PaymentToBeProcessed.BankInfoName = Payment.PaymentInfo1
        PaymentToBeProcessed.BankInfoRoutingNum = Payment.PaymentInfo2
        PaymentToBeProcessed.BankInfoAccountNum = Payment.PaymentInfo3

        If PaymentToBeProcessed.BankInfoAccountNum.Length >= 4 Then
            PaymentToBeProcessed.Last4 = PaymentToBeProcessed.BankInfoAccountNum.Substring(PaymentToBeProcessed.BankInfoAccountNum.Length - 4, 4)
        Else
            PaymentToBeProcessed.Last4 = "XXXX"
        End If

        PaymentToBeProcessed.TransactionTypeID = 1
        PaymentToBeProcessed.Email = Payment.TransactionEmail
        PaymentToBeProcessed.TransactionAmount = Payment.TransactionAmount

        PaymentToBeProcessed.Save()
        PaymentToBeProcessed.SendPaymentToGateway()


        'Run our method to remove the future payment from the Future_Transactions table and enter it into the Future_Transactions_History table as processed
        Payment.ProcessFuturePayment(Payment.FutureTransactionID)



    Next

End Function



Protected Overrides Sub OnStop()
    ' Add code here to perform any tear-down necessary to stop your service.
End Sub

结束类

我已尝试右键单击服务上的设计器视图并添加安装程序,我已更改 ServiceInstaller1 上的 serviceName 和 displayName 属性,然后我已将 ServiceProcessInstaller1 的帐户属性更改为 LocalSystem。我的教程说的下一步是构建,然后它应该创建一个 MyService.exe 但是当我搜索我的解决方案文件和文件夹时,我找不到这个 exe,所以我不确定为什么没有在构建时创建它?我会以错误的方式解决这个问题吗?我应该使用 Windows 任务计划程序启动它,还是应该创建一个安装程序并将其安装在我们的服务器上以在后台持续运行?感谢您提供任何信息或帮助!

【问题讨论】:

    标签: vb.net visual-studio-2012 timer windows-services windows-installer


    【解决方案1】:

    最佳做法是创建 MSI。服务安装程序类被视为反模式,因为 MSI 已经支持服务。见:

    Building and Deploying a Windows Service using IsWiX

    【讨论】:

    • 您好,感谢您的建议,我正在观看视频,但我没有看到可以添加到我的解决方案中的 Windows Insaller XML。我是否需要以某种方式将 IsWix 添加到视觉工作室?谢谢!
    • FWIW,我推荐单独的解决方案。由于这个原因,ISWIX 不支持项目引用。如果您执行相同的解决方案,则需要添加项目依赖项以确保正确的构建顺序。
    猜你喜欢
    • 2016-12-21
    • 2018-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-06
    • 1970-01-01
    • 2017-01-28
    • 2020-12-04
    相关资源
    最近更新 更多