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

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

222275 次浏览

在服务项目中做以下工作:

  1. 在解决方案资源管理器中双击您的服务。Cs 文件。它应该打开一个全灰色的屏幕,并谈论从工具箱中拖动东西。
  2. 然后右键单击灰色区域并选择添加安装程序。这将向您的项目添加一个安装程序项目文件。
  3. 然后在 projectinstaller.cs 的设计视图中就有了两个组件(serviceProcessInstaller1和 serviceInstaller1)。然后,您应该根据需要设置属性,例如服务名称和应该作为其运行的用户。

现在您需要创建一个安装项目。最好的方法是使用安装向导。

  1. 右键单击解决方案并添加一个新项目: 添加 > 新建项目 > 安装和部署项目 > 安装向导

    对于不同版本的 VisualStudio,这可能略有不同。 它位于: 安装模板 > 其他项目类型 > 安装和部署 > VisualStudio 安装程序

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

  3. 在第3个步骤中,选择“ Primaryoutput from...”

  4. 点击完成。

接下来编辑您的安装程序,以确保包含正确的输出。

  1. 在解决方案资源管理器中右键单击安装项目。
  2. 选择 View > Custom Actions (在 VS2008中可能是 View > Editor > Custom Actions)
  3. 右键单击“自定义操作”树中的“安装操作”,然后选择“添加自定义操作...”
  4. 在“选择项目中的项”对话框中,选择“应用程序文件夹”并单击“确定”。
  5. 单击 OK 选择“ Primaryoutput from...”选项。应该创建一个新节点。
  6. 对提交、回滚和卸载操作重复步骤4-5。

可以通过右键单击解决方案中的 Installer 项目并选择 Properties 来编辑安装程序输出名称。将“ Output file name:”更改为您想要的任何内容。通过选择安装程序项目以及查看属性窗口,您可以编辑 Product NameTitleManufacturer等。.

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

我按照 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;
}

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

VisualStudio 部署项目(在 VisualStudio 的下一个版本中也没有得到高度重视和反对)不具有对服务的本机支持。但它们可以使用合并模块。因此,我想看看这篇博客文章,了解如何使用 Windows Installer XML 创建一个合并模块,这个模块可以表达服务,然后在您的 VDPROJ 解决方案中使用该合并模块。

使用 Windows Installer XML-Windows 服务 增强 InstallShield

Windows 服务教程

视频服务

Kelsey 和 Brendan 的解决方案都不适合我在 Visual Studio 2015社区中使用。

下面是我如何使用安装程序创建服务的简短步骤:

  1. 运行 VisualStudio,转到 File->New->Project
  2. 在“搜索已安装的模板”类型 “服务”中选择.NETFramework4
  3. 选择“ Windows 服务”。键入名称和位置。按 OK
  4. 双击 Service1.cs,右键单击 Designer 并选择“ Add Installer”
  5. 双击 projectinstaller.cs。对于 serviceProcessInstaller1,打开“属性”选项卡并将“ Account”属性值更改为“ LocalService”。对于 serviceInstaller1,更改“ ServiceName”并将“ StartType”设置为“ auto”。
  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. Build solution. Right click on project and select 'Open Folder in File Explorer'. Go to bin\Debug.

  8. Create install.bat with below script:

    :::::::::::::::::::::::::::::::::::::::::
    :: 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. Create uninstall.bat file (change in pen-ult line /i to /u)
  10. To install and start service run install.bat, to stop and uninstall run uninstall.bat

对于 VS2017,您需要添加“ MicrosoftVisualStudio2017安装程序项目”VS 扩展。这将为您提供其他 VisualStudioInstaller 项目模板。https://marketplace.visualstudio.com/items?itemName=VisualStudioProductTeam.MicrosoftVisualStudio2017InstallerProjects#overview

要安装 Windows 服务,您可以添加一个新的安装向导类型的项目,并遵循从凯尔西的答案 https://stackoverflow.com/a/9021107/1040040的步骤