如何使用Visual Studio为.net Windows服务创建安装程序

时间:2012-01-26 16:04:14

标签: c# .net visual-studio windows-services windows-installer

如何为使用Visual Studio创建的Windows服务创建安装程序?

6 个答案:

答案 0 :(得分:191)

在服务项目中,执行以下操作:

  1. 在解决方案资源管理器中,双击您的服务.cs文件。它应该显示一个全灰色的屏幕,并讨论从工具箱中拖动内容。
  2. 然后右键单击灰色区域并选择添加安装程序。这会将安装程序项目文件添加到您的项目中。
  3. 然后,您将在ProjectInstaller.cs(serviceProcessInstaller1和serviceInstaller1)的设计视图中拥有2个组件。然后,您应该根据需要设置属性,例如服务名称和应该运行的用户。
  4. 现在您需要制作一个安装项目。最好的办法是使用设置向导。

    1. 右键单击您的解决方案并添加新项目:添加>新项目>设置和部署项目>设置向导

      一个。对于不同版本的Visual Studio,这可能略有不同。 湾Visual Studio 2010位于:安装模板>其他项目类型>设置和部署> Visual Studio安装程序

    2. 在第二步中选择“为Windows应用程序创建安装程序。”

    3. 在第3步中,选择“主要输出来自...”
    4. 点击完成。
    5. 接下来编辑安装程序以确保包含正确的输出。

      1. 右键单击解决方案资源管理器中的安装项目。
      2. 选择查看>自定义操作。 (在VS2008中可能是View> Editor> Custom Actions)
      3. 右键单击“自定义操作”树中的“安装”操作,然后选择“添加自定义操作...”
      4. 在“在项目中选择项目”对话框中,选择“应用程序文件夹”,然后单击“确定”。
      5. 单击“确定”以选择“主要输出...”选项。应该创建一个新节点。
      6. 对提交,回滚和卸载操作重复步骤4 - 5。
      7. 您可以通过右键单击解决方案中的Installer项目来编辑安装程序输出名称,然后选择“属性”。将“输出文件名:”更改为您想要的任何内容。通过选择安装程序项目并查看属性窗口,您可以编辑Product NameTitleManufacturer等...

        接下来构建安装程序,它将生成一个MSI和一个setup.exe。选择您要用于部署服务的任何一个。

答案 1 :(得分:47)

我按照Kelsey的第一组步骤将安装程序类添加到我的服务项目中,但是我没有创建MSI或setup.exe安装程序,而是让服务自行安装/卸载。以下是我可以使用的一个服务示例代码作为起点。

public static int Main(string[] args)
{
    if (System.Environment.UserInteractive)
    {
        // we only care about the first two characters
        string arg = args[0].ToLowerInvariant().Substring(0, 2);

        switch (arg)
        {
            case "/i":  // install
                return InstallService();

            case "/u":  // uninstall
                return UninstallService();

            default:  // unknown option
                Console.WriteLine("Argument not recognized: {0}", args[0]);
                Console.WriteLine(string.Empty);
                DisplayUsage();
                return 1;
        }
    }
    else
    {
        // run as a standard service as we weren't started by a user
        ServiceBase.Run(new CSMessageQueueService());
    }

    return 0;
}

private static int InstallService()
{
    var service = new MyService();

    try
    {
        // perform specific install steps for our queue service.
        service.InstallService();

        // install the service with the Windows Service Control Manager (SCM)
        ManagedInstallerClass.InstallHelper(new string[] { Assembly.GetExecutingAssembly().Location });
    }
    catch (Exception ex)
    {
        if (ex.InnerException != null && ex.InnerException.GetType() == typeof(Win32Exception))
        {
            Win32Exception wex = (Win32Exception)ex.InnerException;
            Console.WriteLine("Error(0x{0:X}): Service already installed!", wex.ErrorCode);
            return wex.ErrorCode;
        }
        else
        {
            Console.WriteLine(ex.ToString());
            return -1;
        }
    }

    return 0;
}

private static int UninstallService()
{
    var service = new MyQueueService();

    try
    {
        // perform specific uninstall steps for our queue service
        service.UninstallService();

        // uninstall the service from the Windows Service Control Manager (SCM)
        ManagedInstallerClass.InstallHelper(new string[] { "/u", Assembly.GetExecutingAssembly().Location });
    }
    catch (Exception ex)
    {
        if (ex.InnerException.GetType() == typeof(Win32Exception))
        {
            Win32Exception wex = (Win32Exception)ex.InnerException;
            Console.WriteLine("Error(0x{0:X}): Service not installed!", wex.ErrorCode);
            return wex.ErrorCode;
        }
        else
        {
            Console.WriteLine(ex.ToString());
            return -1;
        }
    }

    return 0;
}

答案 2 :(得分:21)

Nor Kelsey和Brendan解决方案在Visual Studio 2015社区中对我不起作用。

以下是我使用安装程序创建服务的简要步骤:

  1. 运行Visual Studio,转到文件 -> -> < KBD>项目
  2. 选择.NET Framework 4,在“搜索已安装的模板”中输入'服务'
  3. 选择“Windows服务”。输入名称和位置。按确定
  4. 双击Service1.cs,右键单击设计器并选择“添加安装程序”
  5. 双击ProjectInstaller.cs。对于serviceProcessInstaller1,打开“属性”选项卡,将“帐户”属性值更改为“LocalService”。对于serviceInstaller1,更改“ServiceName”并将“StartType”设置为“Automatic”。
  6. 双击serviceInstaller1。 Visual Studio创建serviceInstaller1_AfterInstall事件。编写代码:

    private void serviceInstaller1_AfterInstall(object sender, InstallEventArgs e)
    {
        using (System.ServiceProcess.ServiceController sc = new 
        System.ServiceProcess.ServiceController(serviceInstaller1.ServiceName))
        {
            sc.Start();
        }
    }
    
  7. 构建解决方案。右键单击项目,然后选择“在文件资源管理器中打开文件夹”。转到 bin \ Debug

  8. 使用以下脚本创建install.bat:

    :::::::::::::::::::::::::::::::::::::::::
    :: Automatically check & get admin rights
    :::::::::::::::::::::::::::::::::::::::::
    @echo off
    CLS 
    ECHO.
    ECHO =============================
    ECHO Running Admin shell
    ECHO =============================
    
    :checkPrivileges 
    NET FILE 1>NUL 2>NUL
    if '%errorlevel%' == '0' ( goto gotPrivileges ) else ( goto getPrivileges ) 
    
    :getPrivileges 
    if '%1'=='ELEV' (shift & goto gotPrivileges)  
    ECHO. 
    ECHO **************************************
    ECHO Invoking UAC for Privilege Escalation 
    ECHO **************************************
    
    setlocal DisableDelayedExpansion
    set "batchPath=%~0"
    setlocal EnableDelayedExpansion
    ECHO Set UAC = CreateObject^("Shell.Application"^) > "%temp%\OEgetPrivileges.vbs" 
    ECHO UAC.ShellExecute "!batchPath!", "ELEV", "", "runas", 1 >> "%temp%\OEgetPrivileges.vbs" 
    "%temp%\OEgetPrivileges.vbs" 
    exit /B 
    
    :gotPrivileges 
    ::::::::::::::::::::::::::::
    :START
    ::::::::::::::::::::::::::::
    setlocal & pushd .
    
    cd /d %~dp0
    %windir%\Microsoft.NET\Framework\v4.0.30319\InstallUtil /i "WindowsService1.exe"
    pause
    
  9. 创建uninstall.bat文件(将pen-ult行/i更改为/u
  10. 安装并启动服务运行install.bat,停止并卸载运行uninstall.bat

答案 3 :(得分:9)

对于VS2017,您需要添加&#34; Microsoft Visual Studio 2017安装程序项目&#34; VS扩展。这将为您提供其他Visual Studio Installer项目模板。 https://marketplace.visualstudio.com/items?itemName=VisualStudioProductTeam.MicrosoftVisualStudio2017InstallerProjects#overview

要安装Windows服务,您可以添加新的设置向导类型项目,并按照Kelsey的回答https://stackoverflow.com/a/9021107/1040040

中的步骤进行操作

答案 4 :(得分:1)

Windows Installer社区将InstallUtil类(ServiceInstaller)视为反模式。这是一个脆弱的过程,重新发明轮子,忽略了Windows Installer内置的服务支持这一事实。

Visual Studio部署项目(在Visual Studio的下一版本中也未得到高度重视和弃用)没有对服务的本机支持。但是他们可以使用合并模块。所以我将看看这篇博客文章,了解如何使用Windows Installer XML创建合并模块,该模块可以表达服务,然后在VDPROJ解决方案中使用该合并模块。

Augmenting InstallShield using Windows Installer XML - Windows Services

IsWiX Windows Service Tutorial

IsWiX Windows Service Video

答案 5 :(得分:1)

我知道这是一个旧线程,但是我只想加上2美分。我一直讨厌您在VS中管理服务项目的方式。这就是为什么我多年来使用Topshelf的原因。退后一步,不要创建服务项目,而是创建控制台项目,然后向其中添加Topshelf。这很简单。

https://github.com/Topshelf/Topshelf