不使用InstallUtil.exe安装Windows服务

ann*_*lie 38 c# deployment install windows-services

我正在尝试部署Windows服务但不太确定如何正确执行.我将它构建为控制台应用程序,我现在将其转换为Windows服务项目,并从服务中的OnStart方法调用我的类.

我现在需要在没有Visual Studio的服务器上安装它,如果我正确理解它意味着我不能使用InstallUtil.exe而必须创建一个安装程序类.它是否正确?

我确实看过上一个问题,安装没有InstallUtil.exe的.NET Windows服务,但我只是想确保我已经正确理解它.

如果我创建了问题的接受答案链接到的类,下一步是什么?将MyService.exe和MyService.exe.config上传到服务器,双击exe文件,Bob是我的叔叔?

该服务只能安装在一台服务器上.

Hoà*_*ong 49

我知道这是一个非常古老的问题,但最好用新信息更新它.

您可以使用sc命令安装服务:

InstallService.bat:

@echo OFF
echo Stopping old service version...
net stop "[YOUR SERVICE NAME]"
echo Uninstalling old service version...
sc delete "[YOUR SERVICE NAME]"

echo Installing service...
rem DO NOT remove the space after "binpath="!
sc create "[YOUR SERVICE NAME]" binpath= "[PATH_TO_YOUR_SERVICE_EXE]" start= auto
echo Starting server complete
pause
Run Code Online (Sandbox Code Playgroud)

使用SC,您还可以执行更多操作:卸载旧服务(如果您之前已经安装过),检查是否存在具有相同名称的服务...甚至将您的服务设置为自动启动.

许多参考资料之一:使用sc.exe创建服务; 如何传入上下文参数

我用这种方式完成了InstallUtil.就个人而言,我觉得使用SC更清洁,更健康.

  • 我认为这是安装Windows服务最简单的方法 (3认同)
  • 这非常简单,应该比其他方法更受欢迎. (2认同)

Geo*_*kos 32

您仍然可以在没有visual studio的情况下使用installutil,它包含在.net框架中

在服务器上,以管理员身份打开命令提示符:

CD C:\Windows\Microsoft.NET\Framework\v4.0.version (insert your version)

installutil "C:\Program Files\YourWindowsService\YourWindowsService.exe" (insert your service name/location)
Run Code Online (Sandbox Code Playgroud)

要卸载:

installutil /u "C:\Program Files\YourWindowsService\YourWindowsService.exe" (insert your service name/location)
Run Code Online (Sandbox Code Playgroud)


Mat*_*vis 18

InstallUtil.exe工具只是针对服务中的安装程序组件的一些反射调用的包装器.因此,它实际上没有做太多,但运用这些安装程序组件提供的功能.Marc Gravell的解决方案只是提供了一种从命令行执行此操作的方法,这样您就不必再依赖InstallUtil.exe目标计算机了.

这是我基于Marc Gravell解决方案的一步一步.

如何在安装后立即启动.NET Windows服务?


Doo*_*obi 5

为什么不创建一个安装项目?这真的很容易.

  1. 将服务安装程序添加到服务中(您在看似无用的服务"设计"表面上执行此操作)
  2. 创建安装项目并将服务输出添加到安装应用程序文件夹
  3. 最重要的是将Service项目输出添加到所有自定义操作

瞧,你已经完成了.

有关更多信息,请参见此处:http: //www.codeproject.com/KB/dotnet/simplewindowsservice.aspx

还有一种方法可以提示用户输入凭据(或提供自己的凭据).


Luc*_*nzo 5

这是一个基础服务类(ServiceBase 子类),可以将其子类化以构建可以从命令行轻松安装的 Windows 服务,无需 installutil.exe。此解决方案源自如何在安装后立即启动 .NET Windows 服务?,添加一些代码以使用调用 StackFrame 获取服务类型

public abstract class InstallableServiceBase:ServiceBase
{

    /// <summary>
    /// returns Type of the calling service (subclass of InstallableServiceBase)
    /// </summary>
    /// <returns></returns>
    protected static Type getMyType()
    {
        Type t = typeof(InstallableServiceBase);
        MethodBase ret = MethodBase.GetCurrentMethod();
        Type retType = null;
        try
        {
            StackFrame[] frames = new StackTrace().GetFrames();
            foreach (StackFrame x in frames)
            {
                ret = x.GetMethod();

                Type t1 = ret.DeclaringType;

                if (t1 != null && !t1.Equals(t) &&   !t1.IsSubclassOf(t))
                {


                    break;
                }
                retType = t1;
            }
        }
        catch
        {

        }
        return retType;
    }
    /// <summary>
    /// returns AssemblyInstaller for the calling service (subclass of InstallableServiceBase)
    /// </summary>
    /// <returns></returns>
    protected static AssemblyInstaller GetInstaller()
    {
        Type t = getMyType();
        AssemblyInstaller installer = new AssemblyInstaller(
            t.Assembly, null);
        installer.UseNewContext = true;
        return installer;
    }

    private bool IsInstalled()
    {
        using (ServiceController controller =
            new ServiceController(this.ServiceName))
        {
            try
            {
                ServiceControllerStatus status = controller.Status;
            }
            catch
            {
                return false;
            }
            return true;
        }
    }

    private bool IsRunning()
    {
        using (ServiceController controller =
            new ServiceController(this.ServiceName))
        {
            if (!this.IsInstalled()) return false;
            return (controller.Status == ServiceControllerStatus.Running);
        }
    }
    /// <summary>
    /// protected method to be called by a public method within the real service
    /// ie: in the real service
    ///    new internal  void InstallService()
    ///    {
    ///        base.InstallService();
    ///    }
    /// </summary>
    protected void InstallService()
    {
        if (this.IsInstalled()) return;

        try
        {
            using (AssemblyInstaller installer = GetInstaller())
            {

                IDictionary state = new Hashtable();
                try
                {
                    installer.Install(state);
                    installer.Commit(state);
                }
                catch
                {
                    try
                    {
                        installer.Rollback(state);
                    }
                    catch { }
                    throw;
                }
            }
        }
        catch
        {
            throw;
        }
    }
    /// <summary>
    /// protected method to be called by a public method within the real service
    /// ie: in the real service
    ///    new internal  void UninstallService()
    ///    {
    ///        base.UninstallService();
    ///    }
    /// </summary>
    protected void UninstallService()
    {
        if (!this.IsInstalled()) return;

        if (this.IsRunning()) {
            this.StopService();
        }
        try
        {
            using (AssemblyInstaller installer = GetInstaller())
            {
                IDictionary state = new Hashtable();
                try
                {
                    installer.Uninstall(state);
                }
                catch
                {
                    throw;
                }
            }
        }
        catch
        {
            throw;
        }
    }

    private void StartService()
    {
        if (!this.IsInstalled()) return;

        using (ServiceController controller =
            new ServiceController(this.ServiceName))
        {
            try
            {
                if (controller.Status != ServiceControllerStatus.Running)
                {
                    controller.Start();
                    controller.WaitForStatus(ServiceControllerStatus.Running,
                        TimeSpan.FromSeconds(10));
                }
            }
            catch
            {
                throw;
            }
        }
    }

    private void StopService()
    {
        if (!this.IsInstalled()) return;
        using (ServiceController controller =
            new ServiceController(this.ServiceName))
        {
            try
            {
                if (controller.Status != ServiceControllerStatus.Stopped)
                {
                    controller.Stop();
                    controller.WaitForStatus(ServiceControllerStatus.Stopped,
                         TimeSpan.FromSeconds(10));
                }
            }
            catch
            {
                throw;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

您所要做的就是在您的实际服务中实现两个公共/内部方法:

    new internal  void InstallService()
    {
        base.InstallService();
    }
    new internal void UninstallService()
    {
        base.UninstallService();
    }
Run Code Online (Sandbox Code Playgroud)

然后在您要安装服务时调用它们:

    static void Main(string[] args)
    {
        if (Environment.UserInteractive)
        {
            MyService s1 = new MyService();
            if (args.Length == 1)
            {
                switch (args[0])
                {
                    case "-install":
                        s1.InstallService();

                        break;
                    case "-uninstall":

                        s1.UninstallService();
                        break;
                    default:
                        throw new NotImplementedException();
                }
            }


        }
        else {
            ServiceBase[] ServicesToRun;
            ServicesToRun = new ServiceBase[] 
            { 
                new MyService() 
            };
            ServiceBase.Run(MyService);            
        }

    }
Run Code Online (Sandbox Code Playgroud)