doovers
doovers

Reputation: 8675

Create service with arguments using SC.exe

I've spent the last 2 hours trying every conceivable way to create a service using sc.exe and pass arguments but I can't seem to get it right.

I've read this SO question and all the answers about 5 times and it's been no help!

From what I read there it seems I should construct the command like this:

sc create MyService binPath= "C:\path\to\myservice.exe --param1=TestString"

My Service OnStart method looks like this:

Protected Overrides Sub OnStart(ByVal args() As String)
    If Not IsNothing(args) Then
        Library.WriteLog("Number of args = " & args.Count)
        If args.Count > 0 Then
            For i = 0 To args.Count - 1
                Library.WriteLog("Arg" & i & ": " & args(i))
            Next
        End If
    End If
End Sub

But everything I've tried yields "Number of Args = 0" in the log

For clarity I've tried the following (plus a few more probably):

sc create MyService binPath= "C:\path\to\myservice.exe --param1=TestString"
sc create MyService binPath= "C:\path\to\myservice.exe --TestString"
sc create MyService binPath= "C:\path\to\myservice.exe --param1=\"TestString\""
sc create MyService binPath= "C:\path\to\myservice.exe -param1=TestString"
sc create MyService binPath= "C:\path\to\myservice.exe -TestString"
sc create MyService binPath= "C:\path\to\myservice.exe -param1=\"TestString\""

I must be missing something really silly here but I'm banging my head off a wall with it!

Upvotes: 4

Views: 7704

Answers (1)

matth
matth

Reputation: 6279

According to this answer and the comments, the args parameter of OnStart is only used when manually setting start parameters in the windows service dialog, which cannot be saved.

You can use the arguments you are setting up by accessing them in the Main method (located in the Service.Designer.vb file by default). Below is an example:

<MTAThread()> _
<System.Diagnostics.DebuggerNonUserCode()> _
Shared Sub Main(ByVal args As String())
    Dim ServicesToRun() As System.ServiceProcess.ServiceBase
    ServicesToRun = New System.ServiceProcess.ServiceBase() {New Service1(args)}
    System.ServiceProcess.ServiceBase.Run(ServicesToRun)
End Sub

You will need to add or modify a constructor to your service class to accept the arguments:

Private ReadOnly _arguments As String()

Public Sub New(ByVal args As String())
    InitializeComponent()
    _arguments = args
End Sub

Then your OnStart method becomes:

Protected Overrides Sub OnStart(ByVal args() As String)
    If Not IsNothing(args) Then
        Library.WriteLog("Number of args = " & _arguments.Count)
        If args.Count > 0 Then
            For i = 0 To args.Count - 1
                Library.WriteLog("Arg" & i & ": " & _arguments(i))
            Next
        End If
    End If
End Sub

Upvotes: 3

Related Questions