Private Sub ProjectInstaller_AfterInstall(ByVal sender As Object, ByVal e As System.Configuration.Install.InstallEventArgs) Handles MyBase.AfterInstall
'Our code goes in this event because it is the only one that will do
'a proper job of letting the user know that an error has occurred,
'if one indeed occurs. Installation will be rolled back if an error occurs.
Dim iSCManagerHandle As Integer
Dim iSCManagerLockHandle As Integer
Dim iServiceHandle As Integer
Dim bChangeServiceConfig As Boolean
Dim bChangeServiceConfig2 As Boolean
Dim ServiceDescription As modAPI.SERVICE_DESCRIPTION
Dim ServiceFailureActions As modAPI.SERVICE_FAILURE_ACTIONS
Dim ScActions(2) As modAPI.SC_ACTION 'There should be one element for each
'action. The Services snap-in shows 3 possible actions.
Dim bCloseService As Boolean
Dim bUnlockSCManager As Boolean
Dim bCloseSCManager As Boolean
Dim iScActionsPointer As New IntPtr
Try
'Obtain a handle to the Service Control Manager, with appropriate rights.
'This handle is used to open the relevant service.
iSCManagerHandle = modAPI.OpenSCManager(vbNullString, vbNullString, _
modAPI.ServiceControlManagerType.SC_MANAGER_ALL_ACCESS)
'Check that it's open. If not throw an exception.
If iSCManagerHandle < 1 Then
Throw New Exception("Unable to open the Services Manager.")
End If
'Lock the Service Control Manager database.
iSCManagerLockHandle = modAPI.LockServiceDatabase(iSCManagerHandle)
'Check that it's locked. If not throw an exception.
If iSCManagerLockHandle < 1 Then
Throw New Exception("Unable to lock the Services Manager.")
End If
'Obtain a handle to the relevant service, with appropriate rights.
'This handle is sent along to change the settings. The second parameter
'should contain the name you assign to the service.
iServiceHandle = modAPI.OpenService(iSCManagerHandle, "ServiceTest", _
modAPI.ACCESS_TYPE.SERVICE_ALL_ACCESS)
'Check that it's open. If not throw an exception.
If iServiceHandle < 1 Then
Throw New Exception("Unable to open the Service for modification.")
End If
'Call ChangeServiceConfig to update the ServiceType to SERVICE_INTERACTIVE_PROCESS.
'Very important is that you do not leave out or change the other relevant
'ServiceType settings. The call will return False if you do.
'Also, only services that use the LocalSystem account can be set to
'SERVICE_INTERACTIVE_PROCESS.
bChangeServiceConfig = modAPI.ChangeServiceConfig(iServiceHandle, _
modAPI.ServiceType.SERVICE_WIN32_OWN_PROCESS + modAPI.ServiceType.SERVICE_INTERACTIVE_PROCESS, _
SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, vbNullString, vbNullString, _
vbNullString, vbNullString, vbNullString, vbNullString, vbNullString)
'If the call is unsuccessful, throw an exception.
If Not bChangeServiceConfig Then
Throw New Exception("Unable to change the Service settings.")
End If
'To change the description, create an instance of the SERVICE_DESCRIPTION
'structure and set the lpDescription member to your desired description.
ServiceDescription.lpDescription = "This is my custom description for my Windows Service Application!"
'Call ChangeServiceConfig2 with SERVICE_CONFIG_DESCRIPTION in the second
'parameter and the SERVICE_DESCRIPTION instance in the third parameter
'to update the description.
bChangeServiceConfig2 = modAPI.ChangeServiceConfig2(iServiceHandle, _
modAPI.InfoLevel.SERVICE_CONFIG_DESCRIPTION, ServiceDescription)
'If the update of the description is unsuccessful it is up to you to
'throw an exception or not. The fact that the description did not update
'should not impact the functionality of your service.
If Not bChangeServiceConfig2 Then
Throw New Exception("Unable to set the Service description.")
End If
'To change the Service Failure Actions, create an instance of the
'SERVICE_FAILURE_ACTIONS structure and set the members to your
'desired values. See MSDN for detailed descriptions.
ServiceFailureActions.dwResetPeriod = 600
ServiceFailureActions.lpRebootMsg = "Service failed to start! Rebooting..."
ServiceFailureActions.lpCommand = "SomeCommand.exe Param1 Param2"
ServiceFailureActions.cActions = ScActions.Length
'The lpsaActions member of SERVICE_FAILURE_ACTIONS is a pointer to an
'array of SC_ACTION structures. This complicates matters a little,
'and although it took me a week to figure it out, the solution
'is quite simple.
'First order of business is to populate our array of SC_ACTION structures
'with appropriate values.
ScActions(0).Delay = 20000
ScActions(0).SCActionType = modAPI.SC_ACTION_TYPE.SC_ACTION_RESTART
ScActions(1).Delay = 20000
ScActions(1).SCActionType = modAPI.SC_ACTION_TYPE.SC_ACTION_RUN_COMMAND
ScActions(2).Delay = 20000
ScActions(2).SCActionType = modAPI.SC_ACTION_TYPE.SC_ACTION_REBOOT
'Once that's done, we need to obtain a pointer to a memory location
'that we can assign to lpsaActions in SERVICE_FAILURE_ACTIONS.
'We use 'Marshal.SizeOf(New modAPI.SC_ACTION) * 3' because we pass
'3 actions to our service. If you have less actions change the * 3 accordingly.
iScActionsPointer = Marshal.AllocHGlobal(Marshal.SizeOf(New modAPI.SC_ACTION) * 3)
'Once we have obtained the pointer for the memory location we need to
'fill the memory with our structure. We use the CopyMemory API function
'for this. Please have a look at it's declaration in modAPI.
modAPI.CopyMemory(iScActionsPointer, ScActions, Marshal.SizeOf(New modAPI.SC_ACTION) * 3)
'We set the lpsaActions member of SERVICE_FAILURE_ACTIONS to the integer
'value of our pointer.
ServiceFailureActions.lpsaActions = iScActionsPointer.ToInt32
'We call bChangeServiceConfig2 with the relevant parameters.
bChangeServiceConfig2 = modAPI.ChangeServiceConfig2(iServiceHandle, _
modAPI.InfoLevel.SERVICE_CONFIG_FAILURE_ACTIONS, ServiceFailureActions)
'If the update of the failure actions are unsuccessful it is up to you to
'throw an exception or not. The fact that the failure actions did not update
'should not impact the functionality of your service.
If Not bChangeServiceConfig2 Then
Throw New Exception("Unable to set the Service failure actions.")
End If
Catch ex As Exception
Throw ex
Finally
'Once you are done you should close/release the handles to the service
'and the Service Control Manager, as well as free the memory that held
'the array of SC_ACTION structures.
Marshal.FreeHGlobal(iScActionsPointer)
If iServiceHandle > 0 Then
bCloseService = modAPI.CloseServiceHandle(iServiceHandle)
End If
bUnlockSCManager = modAPI.UnlockServiceDatabase(iSCManagerLockHandle)
If iSCManagerHandle > 0 Then
bCloseSCManager = modAPI.CloseServiceHandle(iSCManagerHandle)
End If
End Try
'When installation is done go check out your handy work using Computer Management!
End Sub
Install Windows Service with Interacted with Desktop
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.