Home All Groups Group Topic Archive Search About

Coding service dependencies

Author
24 Aug 2006 9:38 AM
Manuel Alves
Hi all,
I've got a windows service that depends on some other services. On the
project installer I state this by using:

Me.myService.ServicesDependedOn = New String() {"Print Spooler", "Net
Logon", "Network Connections"}

The problem:
If the server is not an english version I have to translate the service
names. Here is how I do it for portuguese and "other" (english):

Dim ci As CultureInfo = CultureInfo.CurrentUICulture
If InStr(ci.TwoLetterISOLanguageName, "pt", CompareMethod.Text) > 0 Then
   Me.myService.ServicesDependedOn = _
   New String() {"Spooler de impressão", "Início de sessão de rede",
"Ligações de rede"}
Else
   Me.myService.ServicesDependedOn = _
   New String() {"Print Spooler", "Net Logon", "Network Connections"}
End If

But what if it gets deployed to a German, Spanish or French server?

Do I need to code every possibility or is there a way to reference these
services in a language independent way?

Best regards,
Manuel Alves

Author
25 Aug 2006 6:36 AM
Jeffrey Tan[MSFT]
Hi Manuel,

Sorry, I do not have these localized version of Windows for testing. I
assume that the *Display Name* for these services on the localized Windows
will be different from the English Windows. However, I suspect the "Service
Name" of these services will still use the english name. You may use
Services.msc on these localized Windows to help me to confirm this.

If my suspect is correct, we can just enumerate all the services and
compare *Service Name* with stored english service name. Once one is found,
we can get its "Display Name" for ServicesDependedOn usage. To enumerate
all the serivces and get the *Service Name*, you may use the following code
snippet:

Dim sc As ServiceController() = ServiceController.GetServices()
Dim i As Integer
For i = 0 To sc.Length - 1
   If(sc(i).ServiceName) = "Spooler" Then
          .....
   End If
Next i

If my suspect is incorrect, that is, the *Service Name* is also localized
to non-english name, then we have to use the service binary file name as
the information to identify the service we want.

To get this done, we have to enumerate all the services on the system, and
for each service, we have to p/invoke OpenService win32 API to get the
handle to the this service, finally, we can p/invoke QueryServiceConfig API
to query the full information of this service now. The retrieved
QUERY_SERVICE_CONFIG structure has a field of lpBinaryPathName, which
contains the full binary path of the service. You may use this full binary
path for comparison and identify the service you want. The reason that we
have to p/invoke win32 API to get this done is that .Net did not
encapsulate this function currently.

Hope this helps.

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
Author
25 Aug 2006 3:34 PM
Manuel Alves
Thanks a lot.
The ServiceName is language invariant.
I can just use
Me.myService.ServicesDependedOn = New String() {"Spooler", "Netlogon",
"Netman"}
and it works for all languages.

Here is a small windows form app with a textbox to get the services names
and display names
Imports System.ServiceProcess
Public Class Form1
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
        With TextBox1
            .Text = ""
            .ScrollBars = ScrollBars.Both
            .Dock = DockStyle.Fill
        End With
        Dim sc As ServiceController() = ServiceController.GetServices()
        Dim i As Integer
        For i = 0 To sc.Length - 1
            TextBox1.Text += sc(i).ServiceName & vbTab & vbTab &
sc(i).DisplayName & vbCrLf
        Next i
    End Sub
End Class

Best regards,
Manuel Alves


""Jeffrey Tan[MSFT]"" <je***@online.microsoft.com> wrote in message
Show quoteHide quote
news:15IQPDByGHA.396@TK2MSFTNGXA01.phx.gbl...
> Hi Manuel,
>
> Sorry, I do not have these localized version of Windows for testing. I
> assume that the *Display Name* for these services on the localized Windows
> will be different from the English Windows. However, I suspect the
> "Service
> Name" of these services will still use the english name. You may use
> Services.msc on these localized Windows to help me to confirm this.
>
> If my suspect is correct, we can just enumerate all the services and
> compare *Service Name* with stored english service name. Once one is
> found,
> we can get its "Display Name" for ServicesDependedOn usage. To enumerate
> all the serivces and get the *Service Name*, you may use the following
> code
> snippet:
>
> Dim sc As ServiceController() = ServiceController.GetServices()
> Dim i As Integer
> For i = 0 To sc.Length - 1
>   If(sc(i).ServiceName) = "Spooler" Then
>          .....
>   End If
> Next i
>
> If my suspect is incorrect, that is, the *Service Name* is also localized
> to non-english name, then we have to use the service binary file name as
> the information to identify the service we want.
>
> To get this done, we have to enumerate all the services on the system, and
> for each service, we have to p/invoke OpenService win32 API to get the
> handle to the this service, finally, we can p/invoke QueryServiceConfig
> API
> to query the full information of this service now. The retrieved
> QUERY_SERVICE_CONFIG structure has a field of lpBinaryPathName, which
> contains the full binary path of the service. You may use this full binary
> path for comparison and identify the service you want. The reason that we
> have to p/invoke win32 API to get this done is that .Net did not
> encapsulate this function currently.
>
> Hope this helps.
>
> Best regards,
> Jeffrey Tan
> Microsoft Online Community Support
> ==================================================
> Get notification to my posts through email? Please refer to
> http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
> ications.
>
> Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
> where an initial response from the community or a Microsoft Support
> Engineer within 1 business day is acceptable. Please note that each follow
> up response may take approximately 2 business days as the support
> professional working with you may need further investigation to reach the
> most efficient resolution. The offering is not appropriate for situations
> that require urgent, real-time or phone-based interactions or complex
> project analysis and dump analysis issues. Issues of this nature are best
> handled working with a dedicated Microsoft Support Engineer by contacting
> Microsoft Customer Support Services (CSS) at
> http://msdn.microsoft.com/subscriptions/support/default.aspx.
> ==================================================
> This posting is provided "AS IS" with no warranties, and confers no
> rights.
>
Author
28 Aug 2006 1:51 AM
Jeffrey Tan[MSFT]
Hi Manuel,

Cool! I have never known that ServicesDependedOn can be passed with
ServiceName instead of Display Name. The PlatformSDK document for
*lpDependencies* parameter of CreateService also does not clarify this
point.

Also, since the "Dependencies" tabpage of Services.msc MMC always displays
the depended service with display name instead of Service Name, I used to
think that "Display Name" is the only valid option for ServicesDependedOn
property. However, after viewing the services configuration stored in
HKLM\SYSTEM\CurrentControlSet\Services\, I found that many services really
store the "Service Name" as the *DependOnGroup* key of under the service.
So you are right!

Thank you again for sharing this with us :-)

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.