Coding service dependencies

M

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
 
J

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.
 
M

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]" said:
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.
 
J

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top