简体   繁体   English

以编程方式从 .NET 卸载 Windows 服务

[英]Programmatically uninstall Windows Service from .NET

After searching the web for information, I have managed to create a service which, depending on the command line, can install or uninstall itself, or just run as an application.在网上搜索信息后,我设法创建了一个服务,该服务可以根据命令行自行安装或卸载,或者仅作为应用程序运行。

However, the uninstalling code isn't working correctly.但是,卸载代码无法正常工作。

The related code:相关代码:

Private Function UnInstallService(ByVal args As String(), ByRef errMsg As String) As Boolean
    Dim si As New ServiceInfo

    If (Not GetServiceInfo(args, si)) Then
        errMsg = "Error..."
        Return False
    End If

    If (Not IsServiceInstalled(si.Name)) Then
        errMsg = "Error..."
        Return False
    End If

    Try
        Dim installer As ServiceProcessInstaller = GetServiceInstaller(si)
        Dim stateSaver As IDictionary = New Hashtable
        Try
            installer.Uninstall(stateSaver)
        Catch e As exception
            errMsg = "Error..."
            Return False
        End Try
    Catch e As exception
        errMsg = "Error..."
        Return False
    End Try
End Function

Private Function GetServiceInstaller(ByVal si As ServiceInfo) As ServiceProcessInstaller
    Dim installer As ServiceInstaller = New ServiceInstaller()
    Dim pInstaller As New ServiceProcessInstaller
    pInstaller.Context = New InstallContext("", si.CommandLine)

    installer.Description = si.Description
    installer.DisplayName = si.DisplayName
    installer.ServiceName = si.Name
    installer.StartType = ServiceStartMode.Automatic

    If (si.Account = "LocalSystem") Then
        pInstaller.Account = ServiceAccount.LocalSystem
    ElseIf (si.Account = "LocalService") Then
        pInstaller.Account = ServiceAccount.LocalService
    ElseIf (si.Account = "NetworkService") Then
        pInstaller.Account = ServiceAccount.NetworkService
    Else
        pInstaller.Account = ServiceAccount.User
        pInstaller.Password = si.Password
        pInstaller.Username = si.Account
    End If

    pInstaller.Context.Parameters("assemblypath") = si.FullPath

    pInstaller.Installers.Add(installer)
    installer.Parent = pInstaller

    Return pInstaller
End Function

It throws a NullReferenceException in the call to installer.Uninstall The code for installation is exactly the same, except for checking if the service is installed, and calling installer.Install and then installer.Commit instead of Uninstall.它在调用 installer.Uninstall 时抛出 NullReferenceException ,安装代码完全一样,只是检查服务是否安装,然后调用 installer.Install 然后 installer.Commit 而不是 Uninstall。 I'm passing it exactly the same parameters.我正在传递完全相同的参数。

Your code seems a bit longwinded, all I do to uninstall is call:您的代码似乎有点冗长,我卸载的唯一方法就是调用:

 Dim path As String = Assembly.GetExecutingAssembly().Location
 ManagedInstallerClass.InstallHelper(New String() {"/u", path})

To install all I do is:要安装我要做的就是:

 Dim path As String = Assembly.GetExecutingAssembly().Location
 ManagedInstallerClass.InstallHelper(New String() {path})

And then I've got some code in the constructor of my ProjectInstaller that sets username etc然后我在我的ProjectInstaller的构造函数中有一些代码来设置用户名等

Edit: Though be aware that the documentation for the ManagedInstallerClass has the following quote: This API supports the .NET Framework infrastructure and is not intended to be used directly from your code.编辑:尽管请注意ManagedInstallerClass的文档有以下引用:此 API 支持 .NET Framework 基础结构,并且不打算直接从您的代码中使用。
So it might not be future proof to use it from your own code...所以从你自己的代码中使用它可能不是未来的证明......

I have found the problem here: http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/58505d7b-cb78-4486-88fc-9b86890664e0我在这里发现了问题: http : //social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/58505d7b-cb78-4486-88fc-9b86890664e0

The problem lies in the line问题出在线路上

installer.Uninstall(stateSaver)

which, instead, should have been相反,它应该是

installer.Uninstall(Nothing)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM