2013-04-22 223 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