2013-04-22 122 views
2

我正在创建一个程序,该程序将使用说明创建服务。我目前的代码能够创建一个服务,但无法创建其描述。我当前的代码在VB6中创建服务描述

模块:

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”不是“描述”

回答

1

我看到的问题是,虽然您正确使用Unicode版本的ChangeServiceConfig2,但您正在使用String成员声明UDT。不幸的是,当VB看到一个String类型时,它会自动将其从Unicode转换为本地代码页。这会弄乱你的描述。解决方法是用一个Long成员声明结构体,然后将该值设置为字符串指针的值,例如,

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 
3

是U + 6564。这很清楚:“d”是ASCII 100(64十六进制),“3”是101(65十六进制)。即你有一个字符串编组问题,特别是字符宽度。您需要致电"CreateServiceW",而不是"*A"

对不起,忽略了“描述”实际使用的地方。应该是ChangeServiceConfig2A

+0

好的感谢您的回应,我的做法与您所说的相反,用'ChangeServiceConfig2A'替换'ChangeServiceConfig2W'。它得到了工作。我认为你应该编辑你的答案。 – 2013-04-22 11:17:28