Solved

Problem installing service with vb 2005

Posted on 2008-10-02
8
304 Views
Last Modified: 2013-11-07
I have code that will install and uninstall my service, however, if the service is installed, then uninstalled, it cannot be installed again unless my application is restarted. My code is below if you can find the problem.

Code to install:
      Dim c As New SvcInstaller.ServiceInstaller()
        If c.InstallService("C:\myservice.exe", "ServiceName", "Service description") = True Then
            MessageBox.Show("Success!")
        Else
            MessageBox.Show("Error!")
        End If

Code to uninstall:
 Dim c As New SvcInstaller.ServiceInstaller()
       
        c.UnInstallService("ServiceName")
Imports System

Imports System.Runtime.InteropServices

Namespace SvcInstaller

    Class ServiceInstaller
 

        <DllImport("advapi32.dll")> _

        Public Shared Function OpenSCManager(ByVal lpMachineName As String, ByVal lpSCDB As String, ByVal scParameter As Integer) As IntPtr

        End Function

        <DllImport("Advapi32.dll")> _

        Public Shared Function CreateService(ByVal SC_HANDLE As IntPtr, ByVal lpSvcName As String, ByVal lpDisplayName As String, ByVal dwDesiredAccess As Integer, ByVal dwServiceType As Integer, ByVal dwStartType As Integer, _

         ByVal dwErrorControl As Integer, ByVal lpPathName As String, ByVal lpLoadOrderGroup As String, ByVal lpdwTagId As Integer, ByVal lpDependencies As String, ByVal lpServiceStartName As String, _

         ByVal lpPassword As String) As IntPtr

        End Function

        <DllImport("advapi32.dll")> _

        Public Shared Sub CloseServiceHandle(ByVal SCHANDLE As IntPtr)

        End Sub

        <DllImport("advapi32.dll")> _

        Public Shared Function StartService(ByVal SVHANDLE As IntPtr, ByVal dwNumServiceArgs As Integer, ByVal lpServiceArgVectors As String) As Integer

        End Function

        <DllImport("advapi32.dll", SetLastError:=True)> _

        Public Shared Function OpenService(ByVal SCHANDLE As IntPtr, ByVal lpSvcName As String, ByVal dwNumServiceArgs As Integer) As IntPtr

        End Function

        <DllImport("advapi32.dll")> _

        Public Shared Function DeleteService(ByVal SVHANDLE As IntPtr) As Integer

        End Function

        <DllImport("kernel32.dll")> _

        Public Shared Function GetLastError() As Integer

        End Function
 

        Public Function InstallService(ByVal svcPath As String, ByVal svcName As String, ByVal svcDispName As String) As Boolean

            Dim SC_MANAGER_CREATE_SERVICE As Integer = &H2

            Dim SERVICE_WIN32_OWN_PROCESS As Integer = &H10

            Dim SERVICE_ERROR_NORMAL As Integer = &H1

            Dim STANDARD_RIGHTS_REQUIRED As Integer = &HF0000

            Dim SERVICE_QUERY_CONFIG As Integer = &H1

            Dim SERVICE_CHANGE_CONFIG As Integer = &H2

            Dim SERVICE_QUERY_STATUS As Integer = &H4

            Dim SERVICE_ENUMERATE_DEPENDENTS As Integer = &H8

            Dim SERVICE_START As Integer = &H10

            Dim SERVICE_STOP As Integer = &H20

            Dim SERVICE_PAUSE_CONTINUE As Integer = &H40

            Dim SERVICE_INTERROGATE As Integer = &H80

            Dim SERVICE_USER_DEFINED_CONTROL As Integer = &H100

            Dim SERVICE_ALL_ACCESS As Integer = (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)

            Dim SERVICE_AUTO_START As Integer = &H2

            Try

                Dim sc_handle As IntPtr = OpenSCManager(Nothing, Nothing, SC_MANAGER_CREATE_SERVICE)

                If sc_handle.ToInt32() <> 0 Then

                    Dim sv_handle As IntPtr = CreateService(sc_handle, svcName, svcDispName, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, _

                     SERVICE_ERROR_NORMAL, svcPath, Nothing, 0, Nothing, Nothing, _

                     Nothing)

                    If sv_handle.ToInt32() = 0 Then

                        CloseServiceHandle(sc_handle)

                        Return False

                    Else

                        Dim i As Integer = StartService(sv_handle, 0, Nothing)

                        If i = 0 Then

                            Return False

                        End If

                        CloseServiceHandle(sc_handle)

                        Return True

                    End If

                Else

                    Return False

                End If

            Catch e As Exception

                Throw e

            End Try

        End Function

       

        Public Function UnInstallService(ByVal svcName As String) As Boolean

            Dim GENERIC_WRITE As Integer = &H40000000

            Dim sc_hndl As IntPtr = OpenSCManager(Nothing, Nothing, GENERIC_WRITE)

            If sc_hndl.ToInt32() <> 0 Then

                Dim DELETE As Integer = &H10000

                Dim svc_hndl As IntPtr = OpenService(sc_hndl, svcName, DELETE)

                If svc_hndl.ToInt32() <> 0 Then

                    Dim i As Integer = DeleteService(svc_hndl)

                    If i <> 0 Then

                        CloseServiceHandle(sc_hndl)

                        Return True

                    Else

                        CloseServiceHandle(sc_hndl)

                        Return False

                    End If

                Else

                    Return False

                End If

            Else

                Return False

            End If

        End Function

    End Class

End Namespace

Open in new window

0
Comment
Question by:andy148
  • 5
  • 3
8 Comments
 
LVL 25

Expert Comment

by:SStory
ID: 22651182
I can't understand you question. You said it can't be reinstalled unless the application is restarted.
Do you mean the service itself by the application? Is there another application that works with this service?

If you mean the latter, is there some library that both the application and service share?  If so perhaps that is causing this problem.
0
 

Author Comment

by:andy148
ID: 22661951
I have 2 applications. 1 of them is a regular windows application, the other is a service. the windows application gives the user an option to install and start the service. The user can also stop and uninstall the service. But if they want to install the service again, after it has been installed and uninstalled, the windows application must be restarted. Also, the application and the service do not share any 3rd party dlls, other than Windows dlls. Hope that helps :)
0
 
LVL 25

Expert Comment

by:SStory
ID: 22671415
OK.  Does the windows application talk to the service somehow?  What requires the windows app to be restarted? Are you saying the service does something and it by itself doesn't work when reinstalled until the win app closes?  Or are you saying the win app installs it and then communicates with it and has trouble after uninstall reinstall?  Or is the Windows app just a simple service installation/removal app?

Are you sure that:
CloseServiceHandle(sc_hndl)

Gets called and a handle isn't left open?  This could cause the problem if it isn't.
0
 
LVL 25

Expert Comment

by:SStory
ID: 22671439
http://msdn.microsoft.com/en-us/library/ms682562(VS.85).aspx

Mentions that the delete is only marked for deletion and
"not removed until all open handles to the service have been closed by calls to the CloseServiceHandle function, and the service is not running"

I don't see you stopping the service.  Docs say to use:  ControlService() to stop it
http://msdn.microsoft.com/en-us/library/ms682108(VS.85).aspx
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 

Author Comment

by:andy148
ID: 22682127
I tried placing CloseServiceHandle(sc_hndl) everywhere I possibly could to make sure it got called. Also, before I uninstall the service, I use NET STOP.
0
 
LVL 25

Accepted Solution

by:
SStory earned 500 total points
ID: 22682638
andy148, I honestly don't know. I feel that it is keeping a handle open or an object reference. I don't see any of those so I assume a handle and restarting the app releases it.

I assume the Service is a DotNet Service and thus when you uninstall it, but before you close the app, is the process for that services still running?
0
 

Author Comment

by:andy148
ID: 22691738
I found the problem. It was a handle left open, but it was in the install service instead of the uninstall service. Here is the corrected code in case anyone else reads this. Thanks for your help!
Imports System

Imports System.Runtime.InteropServices

Class SvcInstaller
 

    <DllImport("advapi32.dll")> _

    Public Shared Function OpenSCManager(ByVal lpMachineName As String, ByVal lpSCDB As String, ByVal scParameter As Integer) As IntPtr

    End Function

    <DllImport("Advapi32.dll")> _

    Public Shared Function CreateService(ByVal SC_HANDLE As IntPtr, ByVal lpSvcName As String, ByVal lpDisplayName As String, ByVal dwDesiredAccess As Integer, ByVal dwServiceType As Integer, ByVal dwStartType As Integer, _

     ByVal dwErrorControl As Integer, ByVal lpPathName As String, ByVal lpLoadOrderGroup As String, ByVal lpdwTagId As Integer, ByVal lpDependencies As String, ByVal lpServiceStartName As String, _

     ByVal lpPassword As String) As IntPtr

    End Function

    <DllImport("advapi32.dll")> _

    Public Shared Sub CloseServiceHandle(ByVal SCHANDLE As IntPtr)

    End Sub

    <DllImport("advapi32.dll")> _

    Public Shared Function StartService(ByVal SVHANDLE As IntPtr, ByVal dwNumServiceArgs As Integer, ByVal lpServiceArgVectors As String) As Integer

    End Function

    <DllImport("advapi32.dll", SetLastError:=True)> _

    Public Shared Function OpenService(ByVal SCHANDLE As IntPtr, ByVal lpSvcName As String, ByVal dwNumServiceArgs As Integer) As IntPtr

    End Function

    <DllImport("advapi32.dll")> _

    Public Shared Function DeleteService(ByVal SVHANDLE As IntPtr) As Integer

    End Function

    <DllImport("kernel32.dll")> _

    Public Shared Function GetLastError() As Integer

    End Function
 

    Public Shared Function InstallService(ByVal svcPath As String, ByVal svcName As String, ByVal svcDispName As String) As Boolean

        Dim SC_MANAGER_CREATE_SERVICE As Integer = &H2

        Dim SERVICE_WIN32_OWN_PROCESS As Integer = &H10

        Dim SERVICE_ERROR_NORMAL As Integer = &H1

        Dim STANDARD_RIGHTS_REQUIRED As Integer = &HF0000

        Dim SERVICE_QUERY_CONFIG As Integer = &H1

        Dim SERVICE_CHANGE_CONFIG As Integer = &H2

        Dim SERVICE_QUERY_STATUS As Integer = &H4

        Dim SERVICE_ENUMERATE_DEPENDENTS As Integer = &H8

        Dim SERVICE_START As Integer = &H10

        Dim SERVICE_STOP As Integer = &H20

        Dim SERVICE_PAUSE_CONTINUE As Integer = &H40

        Dim SERVICE_INTERROGATE As Integer = &H80

        Dim SERVICE_USER_DEFINED_CONTROL As Integer = &H100

        Dim SERVICE_ALL_ACCESS As Integer = (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)

        Dim SERVICE_AUTO_START As Integer = &H2

        Try

            Dim sc_handle As IntPtr = OpenSCManager(Nothing, Nothing, SC_MANAGER_CREATE_SERVICE)

            If sc_handle.ToInt32() <> 0 Then

                Dim sv_handle As IntPtr = CreateService(sc_handle, svcName, svcDispName, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, _

                 SERVICE_ERROR_NORMAL, svcPath, Nothing, 0, Nothing, Nothing, _

                 Nothing)

                If sv_handle.ToInt32() = 0 Then

                    CloseServiceHandle(sc_handle)

                    Return False

                Else

                    Dim i As Integer = StartService(sv_handle, 0, Nothing)

                    If i = 0 Then

                        Return False

                    End If

                    CloseServiceHandle(sc_handle)

                    CloseServiceHandle(sv_handle)

                    Return True

                End If

            Else

                Return False

            End If

            CloseServiceHandle(sc_handle)

        Catch e As Exception

            Throw e

        End Try

    End Function
 

    Public Shared Function UnInstallService(ByVal svcName As String) As Boolean

        Dim GENERIC_WRITE As Integer = &H40000000

        Dim sc_hndl As IntPtr = OpenSCManager(Nothing, Nothing, GENERIC_WRITE)

        If sc_hndl.ToInt32() <> 0 Then

            Dim DELETE As Integer = &H10000

            Dim svc_hndl As IntPtr = OpenService(sc_hndl, svcName, DELETE)

            If svc_hndl.ToInt32() <> 0 Then

                Dim i As Integer = DeleteService(svc_hndl)

                If i <> 0 Then

                    CloseServiceHandle(svc_hndl)

                    CloseServiceHandle(sc_hndl)

                    Return True

                Else

                    CloseServiceHandle(sc_hndl)

                    CloseServiceHandle(svc_hndl)

                    Return False

                End If

            Else

                Return False

            End If

            Else

                Return False

        End If

    End Function

End Class

Open in new window

0
 
LVL 25

Expert Comment

by:SStory
ID: 22698930
You are welcome!  I'm glad you got it fixed!
0

Featured Post

Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

Join & Write a Comment

For those of you who don't follow the news, or just happen to live under rocks, Microsoft Research released a beta SDK (http://www.microsoft.com/en-us/download/details.aspx?id=27876) for the Xbox 360 Kinect. If you don't know what a Kinect is (http:…
Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…
This tutorial demonstrates a quick way of adding group price to multiple Magento products.

708 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

17 Experts available now in Live!

Get 1:1 Help Now