Solved

Getting Information about a WIN NT Service from VB ?

Posted on 1998-05-29
9
543 Views
Last Modified: 2008-02-01
Hi !
Has anyone succceeded with retrieving Service Information
using : the API call QueryServiceConfig from VB.
In that case I want to know how !

Like this:
The API requires a pointer to a structure, containing both numeric and string data.  This I have made with API text viewer. Nothing strange with this!

But, the result in the stucture after a successfull call is a mess within the strings. The Numerics works fine, but the separate strings are all placed in the first string and this one starts with a lot of strange caracters in the beginning !

Anyone ?
0
Comment
Question by:Jedi
9 Comments
 
LVL 6

Expert Comment

by:clifABB
ID: 1462000
Can you post your code?
0
 
LVL 4

Expert Comment

by:zsi
ID: 1462001
What service are you trying to get information on?
0
 
LVL 1

Author Comment

by:Jedi
ID: 1462002
I'm trying to get information about a lot of services, in fact
every registered service

0
 
LVL 1

Author Comment

by:Jedi
ID: 1462003
Ok som e code I'm using:
It's a lot of code to post if it's going to compile, the API calls and error handeling and the declarations takes a lot of space.

I'm mostly interested in code that will retrieve cdata using the:
QueryServiceConfig call:
If there is some need for initializing my VB strings before the call or something.
Some code :
'Declarations:
'-------------
Public Declare Function QueryServiceConfig Lib "advapi32.dll" Alias "QueryServiceConfigA" (ByVal hService As Long, lpServiceConfig As QUERY_SERVICE_CONFIG, ByVal cbBufSize As Long, pcbBytesNeeded As Long) As Long

Type QUERY_SERVICE_CONFIG
        dwServiceType As Long
        dwStartType As Long
        dwErrorControl As Long
        lpBinaryPathName As String '* 255
        lpLoadOrderGroup As String '* 255
        dwTagId As Long
        lpDependencies As String '* 255
        lpServiceStartName As String '* 255
        lpDisplayName As String '* 255
End Type

'---------------------------

'Running
'---------------------------
Dim lresult As Long
Dim pcbBytesNeeded As Long
Dim lpServiceConfig As QUERY_SERVICE_CONFIG
Dim cbBufSize As Long

lpServiceConfig.dwServiceType = 0
lpServiceConfig.dwStartType = 0
lpServiceConfig.dwErrorControl=0
lpServiceConfig.lpBinaryPathName = String(255, vbNullChar)lpServiceConfig.lpLoadOrderGroup = String(255, vbNullChar)lpServiceConfig.dwTagId = 0
lpServiceConfig.lpDependencies = String(255, vbNullChar)lpServiceConfig.lpServiceStartName = String(255, vbNullChar)  lpServiceConfig.lpDisplayName = String(255, vbNullChar)      


cbBufSize = LenB(lpServiceConfig)


'Stop Service it first
'    SvcsStop (lpServiceName)
   
    'Open the DB
'    hSCManager = SvcsOpenDB("")
   
'    If hSCManager = Null Then
'        SvcsDisable = False
'        Exit Function
'        Exit Sub
'    End If
       
    'Open the service in question
'    hService = SvcsOpen(hSCManager, lpServiceName)
   
    'Get the right values
lresult = QueryServiceConfig(hService, lpServiceConfig, cbBufSize, pcbBytesNeeded)

'****The strings within the lpServiceConfig structure are a mess.

Hope it gives some clues

0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 

Expert Comment

by:mwalsh111097
ID: 1462004
The problem arises when you try to access null-terminated strings through pointers embedded in a structure.  In order to do this properly, you need to retrieve the string pointers as integer values (define them as "Long" in your VB type, not "String") and then convert them into VB strings.

The following code is a sample of how to do this.  The C++ code is for a DLL which will convert a pointer stored as an integer value into a VB string, and the VB application is a simple demonstration of how to use the library.

==================================
GetBSTR.cpp
==================================
#define WIN32_LEAN_AND_MEAN
#define WIN32_EXTRA_LEAN
#pragma warning( disable : 4201 )
#include <windows.h>
#include <ole2.h>


char const * const gc_p = "TestString";


/*
 *  test function for returning a pointer to a string as a long
 *  integer value...
 */
extern "C" long __declspec( dllexport ) __stdcall GetString( )
    {
    return long( gc_p );
    }


/*
 *  take the given string pointer and convert it to a Visual Basic
 *  string...
 */
extern "C" BSTR __declspec( dllexport ) __stdcall GetStringFromPointer( char const * const p )
    {
    return ::SysAllocStringByteLen( p
                                  , ::strlen( p )
                                  );
    }



==================================
VB Sample Program
==================================
Option Explicit
Declare Function GetString Lib "GetBSTR.dll" Alias "_GetString@0" () As Long
Declare Function GetStringFromPointer Lib "GetBSTR.dll" Alias "_GetStringFromPointer@4" (ByVal l As Long) As String


Sub main()

Dim l As Long
l = GetString()

Dim s As String
s = GetStringFromPointer(l)

End Sub

0
 
LVL 5

Expert Comment

by:bin_huwairib
ID: 1462005
Jedi,

The main problem here is the size of QUERY_SERVICE_CONFIG is not enough for the API function QueryServiceConfig to retrieve the service information, so you must allocate enough space for QUERY_SERVICE_CONFIG structure before calling QueryServiceConfig.
The following steps must be done:
1- Change the variables with string data type in QUERY_SERVICE_CONFIG type to Long data type.
2- Declare a variable as an array with 10 dimensions of this type and pass it to QueryServiceConfig function with the size (10 * length of the first dimension of variable).
3- To get the string use lstrcpy and lstrlen API functions (you don't have to write a C code to do that).

The following example illustrates how to get the information for Schadule service:

Example
=======
Private Type QUERY_SERVICE_CONFIG
 dwServiceType As Long
 dwStartType As Long
 dwErrorControl As Long
 lpBinaryPathName As Long
 lpLoadOrderGroup As Long
 dwTagId As Long
 lpDependencies As Long
 lpServiceStartName As Long
 lpDisplayName As Long
End Type

Private Const GENERIC_READ = &H80000000
Private Const SERVICE_QUERY_CONFIG = &H1

Private Declare Function OpenSCManager Lib "advapi32.dll" Alias "OpenSCManagerA" _
    (ByVal lpMachineName As String, ByVal lpDatabaseName As String, _
    ByVal dwDesiredAccess As Long) As Long
Private Declare Function OpenService Lib "advapi32.dll" Alias "OpenServiceA" (ByVal hSCManager As Long, ByVal lpServiceName As String, ByVal dwDesiredAccess As Long) As Long
Private Declare Function CloseServiceHandle Lib "advapi32.dll" (ByVal hSCObject As Long) As Long
Private Declare Function QueryServiceConfig Lib "advapi32.dll" Alias "QueryServiceConfigA" (ByVal hService As Long, lpServiceConfig As QUERY_SERVICE_CONFIG, ByVal cbBufSize As Long, pcbBytesNeeded As Long) As Long
Private Declare Function lstrcpy Lib "kernel32" Alias "lstrcpyA" (ByVal lpString1 As String, ByVal lpString2 As Long) As Long
Private Declare Function lstrlen Lib "kernel32" Alias "lstrlenA" (ByVal lpString As String) As Long

Private Sub Command1_Click()
 Dim hSCM As Long
 Dim hService As Long
 Dim sMachineName As String
 Dim sDatabaseName As String
 Dim lResult As Long
 Dim pcbBytesNeeded As Long
 Dim lpServiceConfig() As QUERY_SERVICE_CONFIG
 Dim sBinaryPathName As String
 Dim sLoadOrderGroup As String
 Dim sDependencies As String
 Dim sServiceStartName As String
 Dim sDisplayName As String
 
 hSCM = OpenSCManager(sMachineName, sDatabaseName, GENERIC_READ)
 hService = OpenService(hSCM, "Schedule", SERVICE_QUERY_CONFIG)
 
 ReDim lpServiceConfig(100) As QUERY_SERVICE_CONFIG
 lResult = QueryServiceConfig(hService, lpServiceConfig(0), 100 * Len(lpServiceConfig(0)), pcbBytesNeeded)
 
 sBinaryPathName = Space(255)
 lResult = lstrcpy(sBinaryPathName, lpServiceConfig(0).lpBinaryPathName)
 sBinaryPathName = Mid(sBinaryPathName, 1, lstrlen(sBinaryPathName))
 
 sLoadOrderGroup = Space(255)
 lResult = lstrcpy(sLoadOrderGroup, lpServiceConfig(0).lpLoadOrderGroup)
 sLoadOrderGroup = Mid(sLoadOrderGroup, 1, lstrlen(sLoadOrderGroup))
 
 sDependencies = Space(255)
 lResult = lstrcpy(sDependencies, lpServiceConfig(0).lpDependencies)
 sDependencies = Mid(sDependencies, 1, lstrlen(sDependencies))
 
 sServiceStartName = Space(255)
 lResult = lstrcpy(sServiceStartName, lpServiceConfig(0).lpServiceStartName)
 sServiceStartName = Mid(sServiceStartName, 1, lstrlen(sServiceStartName))
 
 sDisplayName = Space(255)
 lResult = lstrcpy(sDisplayName, lpServiceConfig(0).lpDisplayName)
 sDisplayName = Mid(sDisplayName, 1, lstrlen(sDisplayName))
 
 MsgBox "Service Type: " & lpServiceConfig(0).dwServiceType & vbCrLf & _
        "Start Type: " & lpServiceConfig(0).dwStartType & vbCrLf & _
        "Error Control: " & lpServiceConfig(0).dwErrorControl & vbCrLf & _
        "Binary Path Name: " & sBinaryPathName & vbCrLf & _
        "Load Order Group: " & sLoadOrderGroup & vbCrLf & _
        "Tag ID: " & lpServiceConfig(0).dwTagId & vbCrLf & _
        "Dependencies: " & sDependencies & vbCrLf & _
        "Service Start Name: " & sServiceStartName & vbCrLf & _
        "Display Name: " & sDisplayName
 
 Call CloseServiceHandle(hService)
 Call CloseServiceHandle(hSCM)
End Sub


Best regards
Bin Huwairib
0
 
LVL 1

Author Comment

by:Jedi
ID: 1462006
Thanks Mwalsh, but the commented answer from Bin is even better.

Exelent answer from Bin Huwairib ,if you post a answer I'll give you the points !
//Jedi

0
 
LVL 5

Accepted Solution

by:
bin_huwairib earned 500 total points
ID: 1462007
Jedi,

I'm glad that you've solved your problem.


Best regards
Bin Huwairib
0
 
LVL 1

Author Comment

by:Jedi
ID: 1462008
Excellent , That was the kind of answerI was looking for,
An explanation and a solution.
Thanks again

//Jedi
0

Featured Post

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

I’ve seen a number of people looking for examples of how to access web services from VB6.  I’ve been using a test harness I built in VB6 (using many resources I found online) that I use for small projects to work out how to communicate with web serv…
Introduction In a recent article (http://www.experts-exchange.com/A_7811-A-Better-Concatenate-Function.html) for the Excel community, I showed an improved version of the Excel Concatenate() function.  While writing that article I realized that no o…
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now