2

我正在创建一个程序,它将创建一个带有描述的服务。我当前的代码能够创建服务但无法创建其描述。我当前的代码

模块:

Option Explicit
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Private Const ERROR_SERVICE_DOES_NOT_EXIST = 1060&

Private Const SERVICE_WIN32_OWN_PROCESS = &H10&
'Private Const SERVICE_WIN32_SHARE_PROCESS = &H20&
'Private Const SERVICE_WIN32 = SERVICE_WIN32_OWN_PROCESS + _
                                 SERVICE_WIN32_SHARE_PROCESS
'Private Const SERVICE_ACCEPT_STOP = &H1
'Private Const SERVICE_ACCEPT_PAUSE_CONTINUE = &H2
'Private Const SERVICE_ACCEPT_SHUTDOWN = &H4
Private Const SC_MANAGER_CONNECT = &H1&
Private Const SC_MANAGER_CREATE_SERVICE = &H2&
'Private Const SC_MANAGER_ENUMERATE_SERVICE = &H4
'Private Const SC_MANAGER_LOCK = &H8
'Private Const SC_MANAGER_QUERY_LOCK_STATUS = &H10
'Private Const SC_MANAGER_MODIFY_BOOT_CONFIG = &H20
Private Const STANDARD_RIGHTS_REQUIRED = &HF0000
Private Const SERVICE_QUERY_CONFIG = &H1&
Private Const SERVICE_CHANGE_CONFIG = &H2&
Private Const SERVICE_QUERY_STATUS = &H4&
Private Const SERVICE_ENUMERATE_DEPENDENTS = &H8&
Private Const SERVICE_START = &H10&
Private Const SERVICE_STOP = &H20&
Private Const SERVICE_PAUSE_CONTINUE = &H40&
Private Const SERVICE_INTERROGATE = &H80&
Private Const SERVICE_USER_DEFINED_CONTROL = &H100&
Private Const SERVICE_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED Or _
                                       SERVICE_QUERY_CONFIG Or _
                                       SERVICE_CHANGE_CONFIG Or _
                                       SERVICE_QUERY_STATUS Or _
                                       SERVICE_ENUMERATE_DEPENDENTS Or _
                                       SERVICE_START Or _
                                       SERVICE_STOP Or _
                                       SERVICE_PAUSE_CONTINUE Or _
                                       SERVICE_INTERROGATE Or _
                                       SERVICE_USER_DEFINED_CONTROL)
'Private Const SERVICE_AUTO_START As Long = 2
Private Const SERVICE_DEMAND_START As Long = 3
Private Const SERVICE_ERROR_NORMAL As Long = 1
Private Const ERROR_INSUFFICIENT_BUFFER = 122&
Private Enum SERVICE_CONTROL
    SERVICE_CONTROL_STOP = 1&
    SERVICE_CONTROL_PAUSE = 2&
    SERVICE_CONTROL_CONTINUE = 3&
    SERVICE_CONTROL_INTERROGATE = 4&
    SERVICE_CONTROL_SHUTDOWN = 5&
End Enum
Public Enum SERVICE_STATE
    UNINSTALLED = &H0
    STOPPED = &H1
    START_PENDING = &H2
    STOP_PENDING = &H3
    RUNNING = &H4
    CONTINUE_PENDING = &H5
    PAUSE_PENDING = &H6
    PAUSED = &H7
End Enum
Private Type SERVICE_STATUS
    dwServiceType As Long
    dwCurrentState As Long
    dwControlsAccepted As Long
    dwWin32ExitCode As Long
    dwServiceSpecificExitCode As Long
    dwCheckPoint As Long
    dwWaitHint As Long
End Type
Public 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 Declare Function OpenSCManager _
      Lib "advapi32" Alias "OpenSCManagerA" _
      (ByVal lpMachineName As String, ByVal lpDatabaseName As String, _
      ByVal dwDesiredAccess As Long) As Long
Private Declare Function CreateService _
      Lib "advapi32" Alias "CreateServiceA" _
      (ByVal hSCManager As Long, ByVal lpServiceName As String, _
      ByVal lpDisplayName As String, ByVal dwDesiredAccess As Long, _
      ByVal dwServiceType As Long, ByVal dwStartType As Long, _
      ByVal dwErrorControl As Long, ByVal lpBinaryPathName As String, _
      ByVal lpLoadOrderGroup As String, ByVal lpdwTagId As String, _
      ByVal lpDependencies As String, ByVal lp As String, _
      ByVal lpPassword As String) As Long
Private Declare Function DeleteService _
      Lib "advapi32" (ByVal hService As Long) As Long
Private Declare Function CloseServiceHandle _
      Lib "advapi32" (ByVal hSCObject As Long) As Long
Private Declare Function OpenService _
      Lib "advapi32" Alias "OpenServiceA" _
      (ByVal hSCManager As Long, ByVal lpServiceName As String, _
      ByVal dwDesiredAccess As Long) As Long   '** Change SERVICE_NAME as needed
Private Declare Function QueryServiceConfig Lib "advapi32" _
      Alias "QueryServiceConfigA" (ByVal hService As Long, _
      lpServiceConfig As QUERY_SERVICE_CONFIG, _
      ByVal cbBufSize As Long, pcbBytesNeeded As Long) As Long
Private Declare Function QueryServiceStatus Lib "advapi32" _
    (ByVal hService As Long, lpServiceStatus As SERVICE_STATUS) As Long
Private Declare Function ControlService Lib "advapi32" _
        (ByVal hService As Long, ByVal dwControl As SERVICE_CONTROL, _
        lpServiceStatus As SERVICE_STATUS) As Long
Private Declare Function StartService Lib "advapi32" _
        Alias "StartServiceA" (ByVal hService As Long, _
        ByVal dwNumServiceArgs As Long, ByVal lpServiceArgVectors As Long) As Long
Private Declare Function NetWkstaUserGetInfo Lib "Netapi32" (ByVal Reserved As Any, ByVal Level As Long, lpBuffer As Any) As Long
Private Declare Function NetApiBufferFree Lib "Netapi32" (ByVal lpBuffer As Long) As Long

Private Declare Function lstrcpy Lib "kernel32" Alias "lstrcpyA" (ByVal lpString1 As Any, ByVal lpString2 As Any) As Long
Private Declare Function lstrlen Lib "kernel32" Alias "lstrlenA" (ByVal lpString As Any) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Private Declare Function lstrlenW Lib "kernel32" (ByVal lpString As Long) As Long

Private Enum InfoLevel
    SERVICE_CONFIG_DESCRIPTION = 1
    SERVICE_CONFIG_FAILURE_ACTIONS = 2
End Enum

Private Declare Function ChangeServiceConfig2 Lib "advapi32.dll" Alias "ChangeServiceConfig2W" (ByVal hService As Long, ByVal dwInfoLevel As InfoLevel, lpInfo As Any) As Boolean


Private Type SERVICE_DESCRIPTIONW
    lpDescription As String
End Type


' This function installs service on local computer
' It returns nonzero value on error
Public Function CreateNTService(Title As String, Nick As String, Link As String, Description As String) As Long
Dim lp As SERVICE_DESCRIPTIONW
lp.lpDescription = Description
Dim hSCManager As Long
Dim hService As Long, DomainName As String
Dim CSC         As Long

hSCManager = OpenSCManager(vbNullString, vbNullString, _
                       SC_MANAGER_CREATE_SERVICE)
If hSCManager <> 0 Then
' Install service to manual start. To set service to autostart
' replace SERVICE_DEMAND_START to SERVICE_AUTO_START
    hService = CreateService(hSCManager, Nick, _
                       Title, SERVICE_ALL_ACCESS, _
                       SERVICE_WIN32_OWN_PROCESS, _
                       SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, _
                       Link, vbNullString, _
                       vbNullString, vbNullString, "LocalSystem", _
                        "")
    CSC = ChangeServiceConfig2(hService, 1, lp)
    If hService <> 0 Then
        CloseServiceHandle hService
    Else
        CreateNTService = Err.LastDllError
    End If

    CloseServiceHandle hSCManager
Else
    CreateNTService = Err.LastDllError
End If
End Function

形式:

Private Sub Form_Load()
CreateNTService "a", "a", "d:\link", "description"
End
End Sub

问题是这段代码能够创建一些描述,但创建的描述是“敤捳楲瑰潩n”而不是“描述”

4

2 回答 2

2
于 2013-04-22T11:01:48.970 回答
0

The problem that I see is that whilst you are correctly using a Unicode version of ChangeServiceConfig2, you are declaring the UDT with a String member. Unfortunately, when VB sees a String type, it automatically converts it from Unicode to the local code page. This messes up your description. The work around is to declare the structuion with a Long member, and then set this value to that of the string's pointer, e.g.

Option Explicit

Private Const STANDARD_RIGHTS_REQUIRED = &HF0000
Private Const SERVICE_WIN32_OWN_PROCESS = &H10&
Private Const SERVICE_QUERY_CONFIG = &H1&
Private Const SERVICE_CHANGE_CONFIG = &H2&
Private Const SERVICE_QUERY_STATUS = &H4&
Private Const SERVICE_ENUMERATE_DEPENDENTS = &H8&
Private Const SERVICE_START = &H10&
Private Const SERVICE_STOP = &H20&
Private Const SERVICE_PAUSE_CONTINUE = &H40&
Private Const SERVICE_INTERROGATE = &H80&
Private Const SERVICE_USER_DEFINED_CONTROL = &H100&
Private Const SERVICE_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED Or _
                                       SERVICE_QUERY_CONFIG Or _
                                       SERVICE_CHANGE_CONFIG Or _
                                       SERVICE_QUERY_STATUS Or _
                                       SERVICE_ENUMERATE_DEPENDENTS Or _
                                       SERVICE_START Or _
                                       SERVICE_STOP Or _
                                       SERVICE_PAUSE_CONTINUE Or _
                                       SERVICE_INTERROGATE Or _
                                       SERVICE_USER_DEFINED_CONTROL)
Private Const SERVICE_DEMAND_START As Long = 3
Private Const SERVICE_ERROR_NORMAL As Long = 1

Private Const SC_MANAGER_CREATE_SERVICE = &H2&

Private Declare Function OpenSCManager _
      Lib "advapi32" Alias "OpenSCManagerA" _
      (ByVal lpMachineName As String, ByVal lpDatabaseName As String, _
      ByVal dwDesiredAccess As Long) As Long
Private Declare Function CreateService _
      Lib "advapi32" Alias "CreateServiceA" _
      (ByVal hSCManager As Long, ByVal lpServiceName As String, _
      ByVal lpDisplayName As String, ByVal dwDesiredAccess As Long, _
      ByVal dwServiceType As Long, ByVal dwStartType As Long, _
      ByVal dwErrorControl As Long, ByVal lpBinaryPathName As String, _
      ByVal lpLoadOrderGroup As String, ByVal lpdwTagId As String, _
      ByVal lpDependencies As String, ByVal lp As String, _
      ByVal lpPassword As String) As Long

Private Declare Function CloseServiceHandle _
      Lib "advapi32" (ByVal hSCObject As Long) As Long

Private Enum InfoLevel
    SERVICE_CONFIG_DESCRIPTION = 1
    SERVICE_CONFIG_FAILURE_ACTIONS = 2
End Enum

Private Declare Function ChangeServiceConfig2 Lib "advapi32.dll" Alias "ChangeServiceConfig2W" (ByVal hService As Long, ByVal dwInfoLevel As InfoLevel, ByRef lpInfo As SERVICE_DESCRIPTIONW) As Boolean

Private Type SERVICE_DESCRIPTIONW
    lpDescription As Long
End Type

' This function installs service on local computer
' It returns nonzero value on error
Public Function CreateNTService(ByRef Title As String, ByRef ServiceName As String, ByRef BinaryPath As String, ByRef Description As String) As Long

    Dim hSCManager      As Long
    Dim hService        As Long
    Dim DomainName      As String
    Dim CSC             As Long
    Dim lp              As SERVICE_DESCRIPTIONW

    hSCManager = OpenSCManager(vbNullString, vbNullString, _
                           SC_MANAGER_CREATE_SERVICE)

    If hSCManager <> 0 Then
    ' Install service to manual start. To set service to autostart
    ' replace SERVICE_DEMAND_START to SERVICE_AUTO_START
        hService = CreateService(hSCManager, ServiceName, _
                           Title, SERVICE_ALL_ACCESS, _
                           SERVICE_WIN32_OWN_PROCESS, _
                           SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, _
                           BinaryPath, vbNullString, _
                           vbNullString, vbNullString, "LocalSystem", _
                            "")

        lp.lpDescription = StrPtr(Description) ' Set the string pointer.
        CSC = ChangeServiceConfig2(hService, 1, lp)
        If hService <> 0 Then
            CloseServiceHandle hService
        Else
            CreateNTService = Err.LastDllError
        End If

        CloseServiceHandle hSCManager
    Else
        CreateNTService = Err.LastDllError
    End If

End Function
于 2013-04-22T13:09:11.970 回答