Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Problem installing service with vb 2005

Posted on 2008-10-02
8
Medium Priority
?
311 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
NFR key for Veeam Agent for Linux

Veeam is happy to provide a free NFR license for one year.  It allows for the non‑production use and valid for five workstations and two servers. Veeam Agent for Linux is a simple backup tool for your Linux installations, both on‑premises and in the public cloud.

 
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
 

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 2000 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

Google Certified Professional - Cloud Architect

This course (1 of 3) is designed to help students who are interested in Google Cloud Platform (GCP) to become familiar with the platform, navigate the console and learn its capabilities. It will also prepare students for the Google Cloud Architect certification exam.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Welcome my friends to the second instalment and follow-up to our Minify and Concatenate Your Scripts and Stylesheets (http://www.experts-exchange.com/Programming/Languages/.NET/ASP.NET/A_4334-Minify-and-Concatenate-Your-Scripts-and-Stylesheets.html)…
The ECB site provides FX rates for major currencies since its inception in 1999 in the form of an XML feed. The files have the following format (reducted for brevity) (CODE) There are three files available HERE (http://www.ecb.europa.eu/stats/exch…
This is my first video review of Microsoft Bookings, I will be doing a part two with a bit more information, but wanted to get this out to you folks.
In this video, Percona Solution Engineer Dimitri Vanoverbeke discusses why you want to use at least three nodes in a database cluster. To discuss how Percona Consulting can help with your design and architecture needs for your database and infras…

670 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